我看到有人为减速器编写了这段代码:
export default function reducer(state, action) {
switch(action.type) {
case 'ADD_TODO':
Object.assign({}, state, {
todos: [{
text: action.text,
completed: false,
}, ...state.todos]
})
default:
return state;
}
}
为什么不这样做?
case 'ADD_TODO':
return [{text: action.txt, completed: false}, ...state.todos]
有什么区别?
答案 0 :(得分:0)
在Redux中,Splitting Reducers的概念用于在推断新状态时更好地组织。当您将reducer拆分为多个不同的Reducer,然后将它们与combineReducers
组合在一起时,您实际上为每个reducer提供了与其管理的相应状态相对应的状态切片。例如,我可以只为每个管理todos创建一个todo
reducer,只知道状态中的todos,而不是其他任何东西。
在您发布的第一个代码段中,减速机是一个'主人'各种减速机。该示例中的reducer函数是reducer,它处理状态中的所有内容,而不仅仅是todos,并且知道状态中的所有内容。这就是您需要此代码的原因:
Object.assign({}, state, {
todos: [{
text: action.text,
completed: false,
}, ...state.todos]
})
这会创建state
的副本以防止变异(通过Object.assign
),然后使用新的待办事项更新克隆的todos
的{{1}}属性。在这个'主人' reducer,reducer管理所有状态,因此必须克隆状态并更新state
属性。
在第二个示例中,不在同一个reducer中工作。这是因为你只是将一个数组作为新状态返回。这意味着,每当你添加一个待办事项时,todo
就会成为一个数组。不好!只有当您将主减速器拆分为多个时,您的第二个代码段才会起作用,并且您有一个单独的reducer只管理todos。这意味着,todo reducer只能获得各自的状态'。它只会知道状态中的state
属性,并且状态中没有其他内容:
todos
在你的主减速器文件中:
export default function todos(state, action) { //This reducer is only aware of todos in state, nothing else.
switch(action.type) {
case 'ADD_TODO':
return [{text: action.txt, completed: false}, ...state.todos] //This will modify only the `todos` property of state, not the whole state
}
}
在这里,import todos from './your/todo/reducer/file';
combineReducers({
todos
});
' todos
参数只会在状态,即它的切片中收到state
属性。没有其他的。第一个片段将收到整个状态对象作为todos
参数。