嵌套的 Redux Reducer returns 空主状态

Nested Redux Reducer returns null home state

我有用于待办事项的嵌套减速器。我正在为嵌套对象使用“reselect”库。在下面你可以找到 ADD_TODO 减速器和选择器,但是当我调用 ADD_TODO 减速器时;它使状态变成这样;

{
  0: null,
  1: null,
}

添加 Todo Reducer

import { makeSelectTodos } from 'containers/HomePage/selectors';

const initialState = fromJS({
  todos: [],
  visibilityFilter: 'SHOW_ALL',
});

const todo = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        id: action.id,
        text: action.text,
        completed: false,
      };
    default:
      return state;
  }
};

function homeReducer(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        makeSelectTodos(),
        todo(undefined, action),
      ];
    default:
      return state;
  }
}

Selector.js

import { createSelector } from 'reselect';

const selectHome = (state) => state.get('home');

const makeSelectTodos = () => createSelector(
  selectHome,
  (homeState) => homeState.get('todos')
);

export {
  selectHome,
  makeSelectTodos,
};

您似乎想要 return homeReducer 中操作类型为 'ADD_TODO' 的所有待办事项。这不太对。带有待办事项列表的组件必须考虑这一点,它可以通过 selectAllTodos 选择器获取所有待办事项。

您也没有为 makeSelectTodos 函数提供状态。正如我所见,您的选择器 returns 函数,即 returns createSelector 函数。有错误。你需要这样写:

const selectHome = state => state.get('home');
const selectAllTodos = createSelector(
    selectHome,
    homeState => homeState.get('todos')
);

In action creators 选择器可以这样使用:

// action creators:

const addTodoAction = todo => ({
    type: 'ADD_TODO',
    payload: todo
});

const addTodo = todo => (dispatch, getState) => {
    // here you able to use your selectors like:
    // const todos = selectAllTodos(getState());

    return dispatch(addTodoAction(todo));
};

尽可能简化你的 reducer 逻辑:

const todosReducer = (state = [], action) => {
    if (action.type === 'ADD_TODO') {
        return {
            id: action.payload.id,
            text: action.payload.text,
            completed: false
        };
    }

    return state;
};

const visibilityFilterReducer = (state = 'SHOW_ALL', action) => {
    // your visibility filter reducer logic
};

export default combineReducers({
    todos: todosReducer,
    visibilityFilter: visibilityFilterReducer
});

祝你好运! :)

问题出在 mapStateToProps,因为没有使用不可变,所以我得到了不同的数据结构。通过使用不可变 "getIn" 我找到了解决方案。