React/Mobx场景下数组元素选中功能高效实现方案咨询
结论
约束条件下最高效的方案是优化后的独立选中状态存储方案,核心思路是用Set存储选中条目ID替代数组存储选中条目,所有核心操作时间复杂度可降到O(1),且完全符合「不可修改原有接口定义、仅支持扩展」的要求。
现有方案对比
你给出的两个原始方案的toggle操作时间复杂度均为O(n),但可优化空间和适用场景差异很大:
方案a(扩展Item新增selected属性)的局限性
- 数据耦合度高:每次拉取最新的原Item列表时,都需要全量遍历合并已有选中状态,列表规模越大初始化开销越高
- 取选中列表开销高:每次获取选中项都要全量遍历整个Item数组过滤,O(n)开销随列表增长线性上升
- Mobx适配成本高:若原Item实例是接口返回的普通对象,运行时新增的
selected属性可能无法被Mobx自动观测,需要额外配置响应式规则
方案b(独立存储选中内容)的优化空间
你当前用数组存储selectedItems的实现查找效率低,只需把存储结构替换为以ID为索引的Set,即可把查找、增删操作的时间复杂度从O(n)降到O(1),优化后实现如下:
class ItemsStore { public items: Item[] // 存选中项ID,增删查都是O(1)复杂度 public selectedIds = new Set<number | string>() constructor() { makeAutoObservable(this) } public toggleItem(item: Item, checked: boolean) { checked ? this.selectedIds.add(item.id) : this.selectedIds.delete(item.id) } // Mobx计算属性,仅当items或selectedIds变化时才重新计算 get selectedItems(): Item[] { return this.items.filter(item => this.selectedIds.has(item.id)) } // 单条选中状态判断也是O(1) public isSelected(item: Item): boolean { return this.selectedIds.has(item.id) } }
优化后方案的优势
- 完全符合约束:不会修改原Item实例的任何属性和结构,没有数据污染问题,接口返回的新Item列表可直接赋值替换,无需额外的状态合并操作
- 性能最优:选中状态切换、单条选中判断都是O(1)复杂度,仅在需要全量选中列表时才会遍历计算,列表规模达上万条时仍能保持流畅操作
- 适配Mobx特性:Set本身是Mobx支持的可观测类型,计算属性
selectedItems会自动缓存结果,没有不必要的重复计算开销
如果你的业务场景中列表是固定不会更新、且需要高频遍历带选中状态的全量条目,方案a也可使用,其余绝大多数场景优先选择优化后的方案b即可。
内容的提问来源于stack exchange,提问作者dasdachs
相关产品推荐
相关产品推荐

