因此,我正在尝试构建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.js
或immutability-helper
之类的东西,还是应该这样?