这是处理Javascript不变性的正确方法吗?

时间:2018-08-13 17:35:17

标签: javascript reactjs redux immutability immutable.js

因此,我正在尝试构建React-Electron游戏,并且一直对如何正确处理不变性感到头痛。

举例来说,假设我的游戏是交易游戏。我的状态将是这样的:

this.state = {
  player: new Trader(),
  customer: new Trader()
}

Trader类是处理不同交易者的自定义可重用类:

class Trader {
  constructor() {
    // Array of inventories that the trader have
    this.inventory = [];
    this.cash = 0;
  }

  addItemToInventory(item) {
    this.inventory.push(item);
  }
}

马上我们可以看到addItemToInventory的问题。如果我在Component之内调用它,例如:

this.state.player.addItemToInventory({ name: 'Apple', price: 10 });

这将是一种反模式,因为我正试图直接改变React状态,对吧?

因此,在进行了一些研究之后,我想出了一个解决方案:Immutable大师班:

class Immutable {
  getClone() {
    return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
  }
}

getClone函数将返回一个对象,该对象包含所有原型函数和前一个对象的所有属性,换句话说,是一个完美的浅表副本。仅返回像return { ...this }这样的散布对象将不会包含所有原型函数,并且代码会中断。

对于需要与React状态或Redux交互的任何类型的数据,我可以将其扩展为Immutable,例如:

class Trader extends Immutable {
  constructor() {
    super();
    this.inventory = [];
    this.cash = 0;
  }

  addItemToInventoryThenGet(item) {
    const newInventory = [ ...this.inventory ];
    newInventory.push(item);
    return Object.assign(this.getClone(), { inventory: newInventory });
  }
}

每次将商品添加到交易者的库存中时,我都会使用setState覆盖整个Trader实例:

this.setState(prevState => {
  return { 
    player: prevState.player.addItemToInventoryThenGet({
      name: 'Apple',
      price: 10
    }) 
  } 
});

当然,此代码在我的项目中可以完美工作,并且满足React和Redux的不变法则。但是,我认为这种模式讨论得并不太多。那么,对React / Redux专家来说,我这样做正确吗?我需要了解任何隐藏的性能问题或瓶颈吗?

此外,我是否需要使用Immutable.jsimmutability-helper之类的东西,还是应该这样?

0 个答案:

没有答案