React中列表去重需先生成新数组再更新状态:基本类型用[...new Set(arr)];兼容旧环境用filter+indexOf;对象数组按字段用filter+findIndex;更新前处理并推荐函数式setState。

在 React 中,状态更新前对列表数据去重,核心是:先处理数据(去重),再调用 setState(或 useState 的更新函数)。React 状态本身是不可变的,所以必须基于原数据生成一个**新数组**并确保无重复,再更新。
用 Set 快速去重(适合简单值)
如果列表是字符串、数字等基本类型,Set 是最简洁的方式:
说明:Set 自动过滤重复项,再转回数组即可。注意要保证传入的是新数组,避免直接修改原数组。
建议写法:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 用扩展运算符
[...new Set(arr)]创建去重后的新数组 - 不要在
setState中直接操作原 state 数组(如push、splice) - 若需保持原始顺序,
Set默认保留首次出现的顺序,完全满足要求
用 filter + indexOf 去重(兼容老环境或需逻辑控制)
适用于需要兼容不支持 Set 的运行环境,或想自定义去重逻辑(比如忽略大小写):
说明:indexOf 返回元素第一次出现的位置,只有当前索引等于首次索引时才保留,从而实现去重。
建议写法:
arr.filter((item, index) => arr.indexOf(item) === index)- 若处理对象数组,需先序列化或比对关键字段(见下一条)
- 注意:该方法时间复杂度为 O(n²),大数据量时慎用
对象数组按字段去重(常见真实场景)
实际开发中,列表常是对象数组(如 [{id: 1, name: 'A'}, {id: 1, name: 'B'}]),需按 id 或其他唯一字段去重:
说明:不能直接用 Set 或 indexOf 比较对象,因为对象引用不同即视为不同。
建议写法:
- 用
Map缓存已出现的 key(如item.id),遍历中跳过重复 key - 或使用
filter+some判断前面是否已有相同字段值 - 示例:
arr.filter((item, index) => arr.findIndex(v => v.id === item.id) === index)
结合 useState 更新前处理(完整 React 示例)
确保去重发生在 setState 调用之前,且不污染原 state:
说明:函数式更新(prev => ...)可避免闭包问题,尤其在异步或多次更新场景下更可靠。
建议写法:
- 更新前先生成新数组:
const uniqueList = [...new Set([...prev, ...newItems])]; - 再统一更新:
setList(prev => [...new Set([...prev, ...newItems])]); - 如需深比较对象,用
JSON.stringify辅助(仅限结构稳定、无函数/undefined 的简单对象)










