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

这是处理Javascript不变性的正确方法吗?,javascript,reactjs,redux,immutability,immutable.js,Javascript,Reactjs,Redux,Immutability,Immutable.js,所以我正在尝试建立一个React电子游戏,我一直在头疼如何正确处理不变性 举个例子,假设我的游戏是一个交易游戏。我的状态是这样的: this.state = { player: new Trader(), customer: new Trader() } Trader类是一个自定义的可重用类,用于处理不同的交易者: class Trader { constructor() { // Array of inventories that the trader have

所以我正在尝试建立一个React电子游戏,我一直在头疼如何正确处理不变性

举个例子,假设我的游戏是一个交易游戏。我的状态是这样的:

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
的问题。如果我在组件中调用它,如:

this.state.player.addItemToInventory({ name: 'Apple', price: 10 });
这将是一个反模式,因为我试图直接改变反应状态,对吗

因此,在做了一些研究之后,我提出了一个解决方案:一个
不可变的
masterclass:

class Immutable {
  getClone() {
    return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
  }
}
getClone
函数将返回一个包含所有原型函数和前一个对象的所有属性的对象,换句话说,是一个完美的浅拷贝。简单地返回一个扩展对象,如
return{…this}
将不包括所有原型函数,代码将中断

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

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覆盖整个交易员实例:

this.setState(prevState => {
  return { 
    player: prevState.player.addItemToInventoryThenGet({
      name: 'Apple',
      price: 10
    }) 
  } 
});
当然,这段代码在我的项目中非常有效,并且它满足React和Redux的不变法则。然而,我不认为这种模式被讨论得太多。那么,对于React/Redux专家来说,我这样做对吗?是否有任何隐藏的性能问题或瓶颈需要注意


另外,我是否需要使用类似于
Immutable.js
immutability helper
的东西,或者这种方式可以吗?

也许这不是一个直接的答案,但我认为这是我们在React中使用组件而不是类的地方。您不能将
播放器
客户
创建为组件吗?或者是一个组件?我将不得不使用Trader类来编写游戏规则代码,这样它就不能是一个组件:)而是一个有趣的建议@mplungjan我认为我的问题不仅仅是一个代码审查,而是一个关于处理Javascript不变性的普遍问题。我真的需要知道是否应该将此模式应用于所有React代码,因为我真的不喜欢像Immutable.js这样的依赖项。但是谢谢你的建议!我会让交易者构造函数接受参数,然后你可以
返回新的交易者(this.cash,[…this.inventory,item])
,但我不熟悉React,也许这没有意义。。。。