(React.js )初始状态随机生成.每次处理事件时如何防止它重新生成?

2022-01-19 00:00:00 reactjs frontend javascript lifecycle

我正在构建一个玩家可以轮流互相攻击的游戏.所以首先我手动设置namejob并生成lifedamagemagic 随机在 componentWillMount() 中.

I am building a game that players can attack each other by turn. So first I set the name, jobmanually and generate life,damage,magic randomly in componentWillMount().

我希望每次我提交攻击表格时,都会减少被攻击者的一定生命值.但是现在每次我提交时,整个状态都会重新生成(有各种错误).

I hope that every time I submit the attack form, certain amount of life with be reduced from the attacked person. But now every time I submit, the whole state is regenerated(with all kinds of bugs).

我可以做点什么来解决它吗?

Can I do something to solve it?

app.js:https://ghostbin.com/paste/ype2y

attack.js:https://ghostbin.com/paste/wzm3m

推荐答案

我注意到你做了很多:

让玩家 = this.state.players

这是你不应该做的.Array 是 js 中的一个对象,所以在这里你通过引用传递.这意味着对 var players 的每一次修改实际上都会产生副作用并修改你不应该做的状态.我通常建议不要使用 in-place 操作,如 splice,并始终使用状态副本.在这种情况下,您可以这样做:

which you are not supposed to do. Array is an object in js so here you are passing by reference. This means that every modification to the var players actually has side effects and modifies the state which you should never do. I generally recommend to never use in-place operations like splice, and to always use a copy of the state. In this case you can do:

让玩家 = this.state.players.slice()

从那时起,对 players 变量的任何修改都不会影响状态.仔细检查您没有在代码中的其他任何地方执行此操作.最重要的是,您应该只使用构造函数来设置和启动您的状态.否则,每次调用 componentWillMount 方法时,都会重新生成您的状态,这可能不是您期望的行为.

and from then on any modification to the players var does NOT affect the state. Double check you are not doing this anywhere else in your code. On top of that you should use the constructor only to set up and initiate your state. Otherwise every time the componentWillMount method is called your state is regenerated which is probably not the behavior you are expecting.

编辑

我想我可以为您提供更多关于您尝试使用数组做什么的指示,作为一般经验法则,我遵循这种方法.如果我的新状态有一个数组字段,它是前一个状态的子集,那么我使用 .filter 方法,如果我的新状态的数组需要更新它的一些条目,那么我使用 .map 方法.举个玩家删除的例子,我会这样做:

I figured I could give you more pointers for what you are trying to do with arrays, as a general rule of thumb I follow this approach. If my new state has an array field which is a subset of the previous one then I use the .filter method, if the array of my new state needs to update some of its entries then I use the .map method. To give you an example on player deletion, I would have done it this way:

handleDeletePlayer(id) {
  this.setState(prevState => ({
    players: prevState.players.filter(player => player.id !== id)
  }));
}

相关文章