Redux搭配Immer时state.machine_state.machines数组赋值不生效问题
问题根因与修复方案
错误点汇总
- 数据源引用错误
代码中遍历的是外部变量typedMachineState.machine_state.machines,而非当前reducer入参的state,不符合「直接基于state操作」的要求,也会导致生成的新数组和当前状态脱节,Immer无法正确检测变更。 - 过滤逻辑错误
现有逻辑是遍历待删除ID列表,只要有一个ID不等于当前机器ID就插入临时数组,当待删除ID数量≥2时,所有机器都会被保留,完全达不到过滤效果。 - Proxy打印是Immer正常表现
Immer会将所有正在修改的state对象包装为Proxy实现变更跟踪,直接打印Proxy对象看不到原始值,调试时可以引入Immer提供的current函数导出原始值再打印。
你之前赋值不生效的核心原因是错误的过滤逻辑生成的newMachines和原数组内容完全一致,Immer做变更检测时认为没有修改状态,所以不会触发更新,只有赋值为空数组时属于明确变更,才会生效。
修复后代码
写法1:过滤生成新数组赋值(最简洁)
import { current } from 'immer'; // 调试需要时引入 clearMachineState(state, { payload }: ClearMachineStatePayload) { // 转Set提升查找效率 const removeIdSet = new Set(payload.children.map(child => child.id)); // 直接基于当前state过滤 state.machine_state.machines = state.machine_state.machines.filter( machine => !removeIdSet.has(machine.machine_id) ); // 调试查看原始值示例 // console.log(current(state.machine_state.machines)); }
写法2:Immer可变风格直接修改原数组
clearMachineState(state, { payload }: ClearMachineStatePayload) { const removeIdSet = new Set(payload.children.map(child => child.id)); // 倒序遍历避免splice导致索引错乱 for (let i = state.machine_state.machines.length - 1; i >= 0; i--) { if (removeIdSet.has(state.machine_state.machines[i].machine_id)) { state.machine_state.machines.splice(i, 1); } } }
内容的提问来源于stack exchange,提问作者Alex Ironside
相关产品推荐
相关产品推荐

