在Redux状态数组设置指定索引值时状态不更新,请问遗漏了什么?
问题根因
- Redux Toolkit 的
createSlice内部通过 Immer 库实现不可变状态更新,Immer 对超出数组当前长度的索引直接赋值的场景不会触发变更检测:该操作会生成稀疏数组,Immer 的代理逻辑不会主动扩展数组长度识别变更。 - 若初始数组长度为0,或
payload.level不属于合法数组下标类型,也会出现状态更新不生效的问题。
修复方案
下面提供两种可直接落地的修复方式:
方案1:主动扩展数组长度后赋值(保留Immer可变写法)
type Tree = Array<Element>; type SetLayerTreeItem = { payload: Element }; const initialState: Tree = []; const LayersTree = createSlice({ name: 'LayersTree', initialState, reducers: { setLayerTreeItem(state, { payload }: SetLayerTreeItem) { // 先确保数组长度覆盖目标索引 if (payload.level >= state.length) { state.length = payload.level + 1; } state[payload.level] = payload; }, }, });
方案2:返回新数组替换原状态(兼容性最高)
如果担心Immer的代理检测异常,可以直接返回新数组跳过Immer的可变处理:
reducers: { setLayerTreeItem(state, { payload }: SetLayerTreeItem) { const newState = [...state]; // 长度不足时填充空位 while (newState.length <= payload.level) { newState.push(undefined); // 可替换为你需要的默认占位值 } newState[payload.level] = payload; return newState; }, }
内容的提问来源于stack exchange,提问作者Alex Ironside
相关产品推荐
相关产品推荐

