我正在开发一个小应用程序,您可以用它跟踪一些游戏分数。
比赛在两名球员之间进行。玩家可以获得积分,但也可能会受到处罚。它不是从玩家的分数中减去惩罚,而是加到对手的分数上。对手也应该下一轮。
我设置了一个实现上述说明的演示:https://codepen.io/anon/pen/ybLQvR
正如你在演示中看到的那样,它并不起作用:当一名球员受到处罚时,他将获得点球,而不是他的对手。
这是由于setState
内的setTurn
未立即处理。 setScore
仍然使用尚未更新的“旧”状态。
我知道这可以通过将回调传递给setState
而不是对象(请参阅注释代码)来处理,该对象采用先前设置的状态。如果我这样做,事情按预期工作。
但是,我还需要在this.state.turn
调用之外的addScore
中更新状态值(在本例中为setState
)。我怎么做到这一点?我试过this.forceUpdate()
无济于事。
我应该在addScore
回调中包装setState
的整个函数体吗?如果需要,我如何根据this.state.turn
方法返回基于addScore
的任何计算?
附带问题:为什么this.forceUpdate()
无效?它是否仅在不处理状态队列的情况下触发重新呈现组件?
感谢您帮助我!
答案 0 :(得分:1)
我现在看到你在说什么。我不知道你要做的是确保在另一个setState方法之前执行了setState方法。
现在,文档就此事要说:
第二个参数是可选的回调函数 完成setState后执行并重新呈现组件。 通常我们建议使用componentDidUpdate()来实现这种逻辑 代替。
因此,根据他们的建议,您应该使用componentDidUpdate()
。那现在问题是怎么回事。
componentDidUpdate(prevProps, prevState)
这是方法签名。所以我们可以在这里看到先前的状态被传入,我们现在可以通过this.state
访问当前状态。
请参阅codepen了解答案。
基本上 - 我将addScore
和changeTurn
转换为只是setState
的片段的函数。这意味着我们可以将它们与状态更改组合在一起,以进行一次原子操作。并且可以在不为不同场景添加复杂的默认参数的情况下重复使用它们。
其次,我添加了应用这些方法的函数以设置状态。这些是按钮使用的!
最后在componentDidUpdate
函数中,现在有机会根据正在执行的当前操作应用操作。不要为默认操作添加setState,否则您将获得无限循环的更新......