React/Mobx: 选择数组中的项目

React/Mobx: Selecting item in an array

处理从 array 中选择项目的最有效方法是什么。假设接口是在不同的域中定义的,因此您可以扩展接口,但不能更改它。

以下是我想到的两种方法:

a) 为项目添加标志,例如一个selected属性

interface Item extends OriginalItem {
  selected: boolean
}

class ItemsStore {
  public items: Item[]
  
  constructor() {
    makeAutoObservable(this)
  }

  public toggleItem(item, checked) {
     const storedItem = this.items.find(i => i.id === item.id)
     if (storedItem) {
         storedItem.selected = checked 
     }
  }
}

b) 添加一个额外的可观察对象,例如selectedItems

class ItemsStore {
  public items: Item[]
  public selectedItems: Item[]
  
  constructor() {
    makeAutoObservable(this)
  }

  public toggleItem(item, checked) {
     const selectedIndex = this.selectedItems.findIndex(i => i.id === item.id)
     if (checked && selectedIndex === -1) {
       this.selectedItems.push(item)
     } else if (!checked && selectedIndex !== -1) {
       this.selectedItems.splice(selectedIndex, 1)
     }
  }
}

注意:我知道添加和过滤可以以更函数式的编程方式完成,老实说我不知道​​哪种方法适合 Mobx,但这部分没那么重要。

selected 属性 的第一种方法要简单得多,而且更像是“mobx 方式”做事。它也不会改变项目数组,所以例如,如果你有带有 .map 的列表组件,它不会重新渲染额外的时间。

如果您需要 selectedItems,您只需添加 computed getter,它只会在发生变化时重新计算:

class ItemsStore {
  public items: Item[]
  
  constructor() {
    makeAutoObservable(this)
  }

  public toggleItem(item, checked) {
     const storedItem = this.items.find(i => i.id === item.id)
     if (storedItem) {
         storedItem.selected = checked 
     }
  }

  // Will become optimised computed property
  get selectedItems() {
    return this.items.filter(item => item.selected)
  }
}