Диспетчерское действие вызывает неверный редуктор - PullRequest
0 голосов
/ 24 мая 2019

Резюме

Чтобы изучить Redux, я включаю некоторые состояния, действия, редукторы и пытаюсь понять, как они используются в компонентах React. Я настроил тестовый объект ...

const initialState = {
    navigationCount : 0,
    someNumber      : 500,
    someList        : ['aa',22,'c5d6','45615'],
};

... и стремиться к:

  • увеличение navigationCount на 1 при посещении страниц

  • добавить или вычесть из someNumber

  • push() & pop() элементы из someList.

Версия

В настоящее время используется gatsby ^2.5.0, react ^16.8.6 и react-redux ^6.0.1.

код

действия и редукторы

import { combineReducers } from 'redux';
import {
    PAGE_INCREMENT,
    NUMBER_INCREASE,
    NUMBER_DECREASE,
    LIST_PUSH,
    LIST_POP,
} from './actionTypes.js';

// state
const initialState = {
    navigationCount : 0,
    someNumber      : 500,
    someList        : ['aa',22,'c5d6','45615'],
};

// action creators returning actions
export const pageIncrementer = navigationCount => {
    return {
        type: PAGE_INCREMENT,
        navigationCount,
    };
};
export const numberAdder = numberToAdd => {
    return {
        type: NUMBER_INCREASE,
        numberToAdd,
    };
};
export const numberMinuser = numberToMinus => {
    return {
        type: NUMBER_DECREASE,
        numberToMinus,
    };
};
export const listPusher = itemToAdd => {
    return {
        type: LIST_PUSH,
        itemToAdd,
    }
};
export const listPopper = () => {
    return {
        type: LIST_POP,
    }
};

// reducers
const pageIncrementReducer = (state = initialState, action) => {
    switch (action.type) {
        case PAGE_INCREMENT:
            return Object.assign({}, ...state, {
                navigationCount: action.navigationCount+1
            });
        default:
            return state.navigationCount;
    }
};
const numberChanger = (state = initialState, action) => {
    switch (action.type) {
        case NUMBER_INCREASE:
            return Object.assign({}, ...state, {
                someNumber: state.someNumber+action.numberToAdd,
            });
        case NUMBER_DECREASE:
            return Object.assign({}, ...state, {
                someNumber: state.someNumber-action.numberToMinus,
            });
        default:
            return state.someNumber;
    };
};
const listChanger = (state = initialState, action) => {
    switch (action.type) {
        case LIST_POP:
            return Object.assign({}, ...state, {
                someList: state.someList.pop(),
            });
        case LIST_PUSH:
            return Object.assign({}, ...state, {
                someList: state.someList.push(action.itemToAdd),
            });
        default:
            return state.someList;
    }
}

// store
const rootReducer = combineReducers({
    pageIncrementReducer,
    numberChanger,
    listChanger,
});

export default rootReducer;

Реагирующий компонент

import React from 'react';
import Layout from '../components/common/Layout.jsx';
import LandingBanner from '../components/landing/LandingBanner.jsx';
import LandingNavgrid from '../components/landing/LandingNavgrid.jsx';
import LandingApp from '../components/landing/LandingApp.jsx';

import { connect } from 'react-redux';
import {
    PAGE_INCREMENT,
    NUMBER_INCREASE,
    NUMBER_DECREASE,
    LIST_PUSH,
    LIST_POP,
} from '../state/actionTypes';

class LandingPage extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            appliedNum: 2000,
        };
    }

    componentDidMount(){
        // this.props.pageIncrement(); // => numberChanger returned undefined
        // this.props.numberIncrease(4444); // => pageIncrementReducer returned undefined
        // this.props.numberDecrease(4444); // => pageIncrementReducer returned undefined
        // this.props.listPush(4444); // => pageIncrementReducer returned undefined
        this.props.listPop();
    }

    render(){
        return (
            <Layout>
                <LandingBanner/>
                <LandingNavgrid/>
                <LandingApp/>
            </Layout>
        )
    }
}

const filterNumbers = (list=[]) => {
    console.log('filterNumbers list: ', list);
    return list.filter(listElement => !!Number(listElement));
};
const mapStateToProps = (state, ownProps) => {
    return {
        someNumber: state.someNumber,
        someList: filterNumbers(state.someList),
        navigationCount: state.navigationCount,
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        pageIncrement: () => dispatch({ type: PAGE_INCREMENT }),
        numberIncrease: () => dispatch({ type: NUMBER_INCREASE }),
        numberDecrease: () => dispatch({ type: NUMBER_DECREASE }),
        listPush: () => dispatch({ type: LIST_PUSH }),
        listPop: () => dispatch({ type: LIST_POP }),
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps,
)(LandingPage);

Ошибка

redux.js: 449 Uncaught Ошибка: заданное действие «LIST_POP», редуктор "pageIncrementReducer" возвратил неопределенный. Чтобы игнорировать действие, вы должен явно вернуть предыдущее состояние. Если вы хотите, чтобы этот редуктор не удерживая значение, вы можете вернуть null вместо undefined.

1 Ответ

0 голосов
/ 24 мая 2019

Прежде всего, вам всегда нужно возвращать состояние в случае переключателя по умолчанию.

default:
       return state;

...