You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅根据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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 21:33:24