Redux中保持状态不可变性需用展开运算符实现浅拷贝:对象用{...state, key: val},数组用[...arr]等;深层嵌套需逐层展开;推荐使用Redux Toolkit的createReducer或createSlice,基于Immer允许直观修改并自动保证不可变性。

在 Redux 中,保持状态不可变性是核心原则。使用展开运算符(...)是实现浅层拷贝、避免直接修改原 state 的简洁高效方式。
对象状态的浅拷贝
当 state 是一个普通对象时,用展开运算符可快速创建新对象,只覆盖需更新的字段,其余保持不变。
- 写法:return { ...state, count: state.count + 1 };
- 效果:原
state不变,返回一个新对象,仅count更新,其他属性(如name、loading)自动继承 - 注意:仅对第一层属性生效;若
state.user是对象,{ ...state, user: { ...state.user, name: 'Alice' } }才能安全更新嵌套属性
数组状态的不可变更新
对数组做增删改操作时,不能用 push、splice 等会改变原数组的方法,而应结合展开运算符生成新数组。
- 添加元素:return [ ...state, newItem ];
- 删除指定项:return state.filter((_, i) => i !== index); 或 [ ...state.slice(0, index), ...state.slice(index + 1) ]
- 更新某一项:return state.map((item, i) => i === index ? { ...item, done: true } : item);
处理多层嵌套结构
深层嵌套对象或数组更新时,需逐层展开,确保每一级引用都新建。
- 例如 state 结构为
{ users: [ { id: 1, profile: { age: 25 } } ] },要更新第一个用户的 age: - return {
- ...state,
- users: state.users.map((u, i) =>
- i === 0 ? { ...u, profile: { ...u.profile, age: 26 } } : u
- )
- };
配合 createReducer 或 Redux Toolkit 更省心
虽然手写 reducer 可用展开运算符完成不可变更新,但更推荐使用 @reduxjs/toolkit 中的 createReducer 或 createSlice,它们内部基于 Immer,允许你“直接修改”草稿状态,自动产出不可变新状态。
- 例如:builder.addCase(updateUser, (state, action) => { state.users[0].profile.age = 26; })
- 写法更直观,底层仍保证不可变性,避免手动展开出错

















