这是一个有效的 redux reducer 吗?
function reducer(state={ byId: {}, ids: [] }, action) {
switch (action.type) {
case 'ADD':
state = { ...state }
state.byId[action.id] = action.value
state.ids.push(action.id)
return state
default:
return state
}
}
整个状态首先是浅克隆的,因此将返回一个新对象,但内部对象保持不变并发生变异。
还是我必须做类似的事情:
function reducer(state={ byId: {}, ids: [] }, action) {
switch (action.type) {
case 'ADD':
return {
...state,
byId: {
...state.byId,
[action.id]: action.value
},
ids: [ ...state.ids, action.id ]
}
default:
return state
}
}
我在第一种方法中看到的副作用是在 DevTools LogMonitor 中:
byId
)将显示与最新状态相同的值,即使它以前是其他状态它只是 LogMonitor 中的一个错误,还是第二种方法是正确的? 如果我在突变之前添加state = _.cloneDeep(state)
它实际上工作正常,证明 LogMonitor 重用相同的对象,因此具有相同的值。
该应用程序的其余部分运行良好,并且@connect
ed 视图可以正确更新。
后一个示例是您需要做的。 显然,如果您要嵌套内容,这可能会有些冗长。 有几个实用程序库试图为您抽象,我在我的 Redux 库列表的不可变数据页面中列出了其中的一些。
还原剂成分也有助于此。
function byId(state = {}, action) {
switch (action.type) {
case 'ADD':
return {
...state,
[action.id]: action.value
}
default:
return state
}
}
function ids(state = [], action) {
switch (action.type) {
case 'ADD':
return [ ...state, action.id ]
default:
return state
}
}
const reducer = combineReducers({
byId,
ids
})
@gaearon @markerikson谢谢。 我最终编写了一个管理动态索引列表(按 ID)的高阶归约器
代码: https ://gist.github.com/elado/95484b754f31fcd6846c7e75de4aafe4
最有用的评论
还原剂成分也有助于此。