(React.js )初始状态随机生成.每次处理事件时如何防止它重新生成?
我正在构建一个玩家
可以轮流互相攻击的游戏.所以首先我手动设置name
、job
并生成life
、damage
、magic
随机在 componentWillMount()
中.
I am building a game that players
can attack each other by turn. So first I set the name
, job
manually 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)
}));
}
相关文章