前端更新数组保证项唯一需用id查重、避免直接修改原数组,新增/更新走“查—判—改”,删除用filter,批量用Map去重,推荐Immer简化不可变操作。

在前端状态树(如 Redux、Zustand 或自管理的 React state)中更新数组时保证项唯一,核心是避免直接修改原数组、用唯一标识(如 id)做查重,并在新增/更新/删除时统一走“查—判—改”逻辑。
用 id 字段作为唯一键做查找和替换
不要依赖数组索引或内容全等(=== 或 JSON.stringify),而是约定每项有稳定、不可变的 id(字符串或数字)。插入或更新前先用 findIndex 或 some 判断是否已存在:
// 示例:添加或更新一个 item
const newItem = { id: '123', name: 'Alice' };
const existingIndex = state.items.findIndex(i => i.id === newItem.id);
if (existingIndex >= 0) {
// 已存在 → 替换
state.items[existingIndex] = newItem;
} else {
// 不存在 → 推入
state.items.push(newItem);
}
用 reduce 或 Map 一次性去重合并(适合批量操作)
当一次处理多个新项(如 API 批量返回),用 reduce 构建以 id 为 key 的临时映射,再转回数组,天然去重且保留最后出现的版本:
将一个或多个 UI 原型图、线框图、产品截图或设计稿转换为标准化、可直接交付的 PRD 风格文档,供产品、设计、前端和测试共同使用。适用于 Codex 需要分析 PC 网页、桌面端、移动端、响应式页面、独立弹窗、表单、表格、看板、数据大屏或多页面流程截图,还原页面结构与交互,强制套用固定文档模板,抽取跨页面共享规则,或把一组原型沉淀为单页规范文档加整体业务流程文档的场景。不适用于纯视觉审美点评、代码实现、接口设计、埋点方案、竞品分析或无 UI 输入的业务需求创作。
const newItems = [{ id: '123', val: 'A' }, { id: '456', val: 'B' }, { id: '123', val: 'A-updated' }];
const uniqueById = newItems.reduce((map, item) => {
map.set(item.id, item); // 后来者覆盖前者
return map;
}, new Map());
const deduped = Array.from(uniqueById.values()); // [{ id: '123', val: 'A-updated' }, { id: '456', val: 'B' }]
删除时按 id 过滤,避免副作用
删除不是靠 splice(index)(易错且难维护),而是用 filter 创建新数组:
立即学习“Java免费学习笔记(深入)”;
// 安全删除 const idToDelete = '123'; state.items = state.items.filter(item => item.id !== idToDelete);
配合 Immer 简化不可变更新(推荐)
用 Immer 可写可变语法,自动产出不可变新数组,同时保持 id 去重逻辑清晰:
import { produce } from 'immer';
const nextState = produce(state, draft => {
const idx = draft.items.findIndex(i => i.id === newItem.id);
if (idx >= 0) {
draft.items[idx] = newItem;
} else {
draft.items.push(newItem);
}
});

















