了解 redux 中的 reducer 和 combineReducers

Understanding reducers and combineReducer in redux

所以我正在使用 redux,我写了一个 reducer 来管理待办事项;

import { combineReducers } from "redux";

import { ADD_TODO, COMPELETE_TODO, REMOVE_TODO } from "./actiontypes";

const initialState = {
    todos: [],
};

const rootReducer = (state = initialState, action) => {
    switch (action.type) {
        case ADD_TODO:
            return {
                ...state,
                todos: [...state.todos, action.payload],
            };
        case COMPELETE_TODO:
        case REMOVE_TODO:
            return {
                ...state,
                todos: state.todos.filter(
                    (todo) => state.todos.indexOf(todo) != action.payload
                ),
            };
        default:
            return state;
    }
};

export default combineReducers({
    rootReducer,
});

如您所见,我创建了一个 reducer 和用户 combineReducer,然后将其传递给存储在其他文件中,并且工作正常。

现在我对 combineReducer 的理解是,当我们单独编写它们时,它结合了分离的 reducer。因此,如果我将上面的减速器(因为我只有一个减速器)更改为以下;

import { ADD_TODO, COMPELETE_TODO, REMOVE_TODO } from "./actiontypes";

const initialState = {
    todos: [],
};

const rootReducer = (state = initialState, action) => {
    switch (action.type) {
        case ADD_TODO:
            return {
                ...state,
                todos: [...state.todos, action.payload],
            };
        case COMPELETE_TODO:
        case REMOVE_TODO:
            return {
                ...state,
                todos: state.todos.filter(
                    (todo) => state.todos.indexOf(todo) != action.payload
                ),
            };
        default:
            return state;
    }
};

export default rootReducer;

并将其传递给状态,但它给出了错误。当我尝试使用 useSelector;

访问 todos 时,它给出了 undefined
const {todos} = useSelector(state => ({
    todos: state.rootReducer.todos
}))

所以我认为我没有正确理解 combineReducers。请解释导致上述错误的原因。

Combine reducer根据你传入的对象的key,为每个reducer控制的state添加命名空间。当你不使用combine reducer时,不会有命名空间。所以将 state.rootReducer 改为 state.

combineReducers 创建一个reducer 来分离组合reducer 的状态。在 documentation 他们展示了这个例子:

rootReducer = combineReducers({potato: potatoReducer, tomato: tomatoReducer})

这将产生以下状态对象

{
  potato: {
    // ... potatoes, and other state managed by the potatoReducer ...
  },
  tomato: {
    // ... tomatoes, and other state managed by the tomatoReducer, maybe some nice sauce? ...
  }
}

因此当你写

combineReducers({
    rootReducer,
});

状态对象将是

{
    rootReducer: {
       // rootReducer's state
    }
}

在您的第二个示例中,您只是 return rootReducer。因此没有单独的状态。 rootReducer 对根状态进行操作。因此,您必须调整选择。

const {todos} = useSelector(state => ({
    todos: state.todos
}))