如何在TypeScript的Reducer中更新数组重复元素而非新增?
修改Reducer逻辑:遇到重复元素时更新原有项而非跳过
要实现「遇到重复unitId的设备时更新原有元素,而非跳过」的逻辑,需替换原代码中过滤重复项的逻辑,改为替换已存在项 + 新增未存在项的处理方式,以下是修改后的完整代码:
export function reducer( state: IDeviceState = initialState, action: DeviceActions.AllDeviceActions ): IDeviceState { switch (action.type) { case DeviceActions.GET_DEVICE_BY_ID_SUCCESS: { const { payload } = action; const devices = Array.isArray(payload) ? payload .map(pushBranches) .flat() .filter((device) => device !== null) : [pushBranches(payload)].filter((device) => device !== null); // 构建新设备的unitId-设备映射表,快速查找替换项 const newDeviceMap = new Map( devices.map(device => [device.result.unitId, device]) ); // 获取原数组中已存在的所有unitId const existingUnitIds = new Set(state.devices.map(d => d.result?.unitId)); // 遍历原设备数组,替换已存在的设备 const updatedExistingDevices = state.devices.map(device => { const replacement = newDeviceMap.get(device.result?.unitId); return replacement || device; }); // 筛选出新设备中未在原数组出现的项,用于新增 const newDevicesToAdd = devices.filter(device => !existingUnitIds.has(device.result.unitId)); // 合并得到最终设备数组 const finalDevices = [...updatedExistingDevices, ...newDevicesToAdd]; return { ...state, devices: finalDevices, loading: false, loaded: true, error: null, }; } default: { return state; } } } function pushBranches(devices: any) { if (devices.result) { return devices; } return null; }
关键修改说明:
- 用
Map存储新设备的unitId与设备对象的映射,避免多次遍历查找,提升效率 - 遍历原设备数组时,对每个元素检查是否有对应的新设备,有则替换为新设备,无则保留原元素
- 单独筛选出新设备中未在原数组出现的项,追加到处理后的原数组末尾,确保新设备正常添加
- 最终合并后的数组既完成了重复项的更新,也保留了原有未修改的元素,同时新增了全新设备
内容的提问来源于stack exchange,提问作者Vihan Gammanpila
相关产品推荐
相关产品推荐

