如何仅根据ID修改Reducer对象中的指定数据条目
Redux Reducer 跨分组按ID更新项实现
核心思路:不需要提前感知外层分组key,遍历clientData下的全部分组,匹配到目标ID所在的数组位置后,遵循Redux不可变更新规则替换对应项即可。
原生JS 标准实现(无额外依赖)
该写法完全遵循Redux原生不可变更新要求,不会修改原state的任何引用:
// 初始state参考 const initialState = { clientData : { 1080 : [{ID : 1111,name : 'John'},{ID : 2222,name : 'Stan'}], 1090 : [{ID : 3333,name : 'Adam'},{ID : 4444,name : 'Alan'}] } } // 对应action约定:{ type: 'UPDATE_CLIENT_ITEM', payload: { targetId: 4444, newItem: {ID: 4444, name: 'New Value'} } } function clientReducer(state = initialState, action) { switch (action.type) { case 'UPDATE_CLIENT_ITEM': { const { targetId, newItem } = action.payload; // 浅拷贝外层clientData对象 const updatedClientData = { ...state.clientData }; // 遍历所有分组,无需提前知道分组key for (const groupKey of Object.keys(updatedClientData)) { const currentGroup = updatedClientData[groupKey]; // 查找当前分组内目标项的索引 const targetIndex = currentGroup.findIndex(item => item.ID === targetId); if (targetIndex !== -1) { // 生成新数组替换原分组,不修改原数组 updatedClientData[groupKey] = [ ...currentGroup.slice(0, targetIndex), newItem, ...currentGroup.slice(targetIndex + 1) ]; // 找到目标后终止遍历,减少无效计算 break; } } return { ...state, clientData: updatedClientData }; } default: return state; } }
Redux Toolkit 简化实现(内置Immer)
如果使用Redux Toolkit(官方推荐写法),内置Immer支持直接写“可变”语法,底层会自动生成不可变更新结果,代码更简洁:
import { createSlice } from '@reduxjs/toolkit'; const clientSlice = createSlice({ name: 'client', initialState: { clientData : { 1080 : [{ID : 1111,name : 'John'},{ID : 2222,name : 'Stan'}], 1090 : [{ID : 3333,name : 'Adam'},{ID : 4444,name : 'Alan'}] } }, reducers: { updateClientItem(state, action) { const { targetId, newItem } = action.payload; // 遍历全部分组 for (const group of Object.values(state.clientData)) { const target = group.find(item => item.ID === targetId); if (target) { // 直接修改即可,Immer会自动处理不可变更新 Object.assign(target, newItem); break; } } } } }); // 导出action和reducer直接使用即可 export const { updateClientItem } = clientSlice.actions; export default clientSlice.reducer;
关键说明
- 所有写法都不需要依赖外层分组key,自动遍历定位目标项
- 原生写法严格保证所有层级的引用更新,不会出现原state被篡改、组件不更新的问题
- 匹配到目标项后立即终止循环,没有多余性能损耗
内容的提问来源于stack exchange,提问作者Duchere
相关产品推荐
相关产品推荐

