为什么Redux中使用createSlice时push生效但直接赋值concat结果不生效
问题核心原因
你遇到的这个问题本质是Redux Toolkit底层依赖的Immer库的更新规则限制导致的,首先先纠正你第一个示例代码的笔误:你写的const initialState = { [] }属于语法错误,结合你的描述你应该是想把初始state直接定义为数组,即const initialState = []。
具体规则说明
Immer会给reducer传入的state套一层代理草稿对象,你可以通过两种合法方式更新状态:
- 直接修改这个草稿对象的内部内容/属性,Immer会自动追踪修改生成新的不可变状态,不需要额外返回值
- 直接返回一个全新的状态值,完全替换原有的状态
你第一种写法失效的原因很明确:state = state.concat(action.payload)这句代码做了两件事:首先调用concat生成了一个包含新数据的全新数组,之后把当前reducer作用域内的局部变量state的引用指向了这个新数组。但你既没有修改原来的Immer代理草稿数组的内容,也没有把这个新数组作为返回值返回,Immer无法感知到你做了修改,自然不会更新状态。
其他写法生效的原因
- 使用
push的写法:push是数组的变异方法,会直接修改原数组(也就是Immer代理的草稿数组)的内容,符合Immer的第一条更新规则,因此可以正常触发状态更新。 - 改为嵌套对象后
state.users = state.users.concat(...)的写法:这时候你修改的是Immer代理草稿对象(state这个对象)的users属性,属于对草稿对象内部属性的修改,Immer可以追踪到这个修改,因此可以正常更新。
第一种写法的修复方案
如果要坚持用concat实现更新,不需要给state变量赋值,直接返回concat的结果即可:
loadUsers(state, action) { return state.concat(action.payload); }
内容的提问来源于stack exchange,提问作者hamzeh_pm
相关产品推荐
相关产品推荐

