用 Set 实现多选组件增量更新,核心是将选中项视为动态集合,只关注新增与取消项;初始化用 new Set(),操作用 add/delete,获取用 [...set];需保存前后 Set 快照计算差集;React 中须每次返回新 Set 实例以触发重渲染。

用 Set 实现多选组件的“增量更新”,核心是把选中项当作一个动态集合,只关注“新增了哪些”“取消了哪些”,而不是每次都全量比对或重置状态。它天然适合记录唯一、可变的选中 ID 列表,并高效计算差值。
用 Set 存储当前选中项
初始化时用 new Set() 替代数组或对象,避免重复添加、手动去重:
- 点击选项时调用 set.add(id)(已存在则无影响)
- 取消选中时调用 set.delete(id)
- 获取所有选中项用 [...set] 或 Array.from(set)
对比前后状态,提取“增量变化”
要实现真正的增量逻辑(比如只发新增/取消的 ID 给后端),需保存上一次的 Set 快照,再用差集计算变化:
- 上次选中:let prev = new Set(current);
- 本次操作后:let next = new Set(current);
- 新增项:[...next].filter(id => !prev.has(id))
- 取消项:[...prev].filter(id => !next.has(id))
配合 React(或其他框架)做轻量更新
在组件中,不必每次 setState 全量数组;可用函数式更新 + Set 差值优化:
- 状态定义为 const [selectedSet, setSelectedSet] = useState(new Set())
- 点击处理:setSelectedSet(prev => { const next = new Set(prev); next.has(id) ? next.delete(id) : next.add(id); return next; });
- 副作用中(如 useEffect)再基于 prev/next 计算增量并触发 API
注意边界:Set 无法直接响应式监听
Set 本身不是响应式数据结构,不能直接作为 React state 的值来触发重渲染(因为 Set 对象引用不变时,React 浅比较会跳过更新):
- 必须每次返回 new Set() 或 new Set(iterable) 来确保引用变化
- 避免直接修改 state 中的 Set 实例(如 selectedSet.add(id)),这不会触发更新
- 如果用 Zustand / Pinia 等状态库,也需确保 setter 返回新实例,或配合 immer 等工具

















