我做了一个简单的剪刀石头布游戏。在onclick
期间,我调用一个函数以添加数字并更改状态。然后,在该函数中,我再调用2个函数,其中一个从1到3之间选择一个随机数,并将其转换为石头/纸/剪刀,然后将其分配给状态,然后另一个函数找出谁赢了:
addToInput = val =>{
this.setState({
input:val
});
this.picknum();
this.pickwin();
}
https://codepen.io/russiandobby/pen/xeRYzw?editors=0002
起初我以为picknum
和pickwin
将同时执行,但是即使我尝试在pickwin
中调用picknum
,它仍然不会工作。
似乎发生的事情是,当执行pickwin
时,它看起来是一个旧状态,而不是被picknum
改变的状态。
如何解决此问题?
答案 0 :(得分:0)
setState是异步的(或者至少可以是异步的),因此无法保证在转到下一行代码时状态已更新。如果在设置状态后需要运行某些内容,则可以放它放在componentDidUpdate生命周期挂钩中,或者将回调传递给setState作为第二个参数。
例如,您可以跳过在addToInput函数中执行pickWin的操作,而改为使用componentDidUpdate函数,如下所示:
componentDidUpdate(prevProps, prevState) {
this.pickWin();
}
这就是说,而不是设置状态,然后等待它更新,然后再次设置状态,我建议您将代码重构为只调用一次setState。如果您多次调用它,则有可能导致多个渲染,但看起来这些都打算成为同一操作的一部分。也许更新您的pickNum和pickWin函数以返回一个值,而不是设置状态本身,然后用结果调用一次setState
picknum () {
let aipick = ["rock","paper","scisors"];
let temp = Math.floor(Math.random() * 3) + 0 ;
return aipick[temp]
}
pickWin(userChoice, aiChoice) {
if (userChoice === 'rock' && aiChoice == 'scisors') {
return 'USER WINS';
}
// etc
}
addToInput = val => {
let aiChoice = pickNum();
let winner = pickWin(val, aiNum);
this.setState({
aiChoice: aiChoice,
whowon: winner,
input: val,
})
}
答案 1 :(得分:0)
好吧,似乎回调可以是解决方案之一,所以我尝试做的就是这个
picknum (){
let aipick=["rock","paper","scisors"];
let temp =Math.floor(Math.random() * 3) + 0 ;
this.setState({
aichoice:aipick[temp]
},function(){
this.pickwin();
}
)
}
////////////
addToInput = val =>{
// console.log('add function');
this.setState({
input:val
},function(){
this.picknum();
}
);
}
似乎现在可以工作。
答案 2 :(得分:-1)
这是javascript的异步机制
this.setState({
input:val
});
如果要同步。让我们使用异步/等待。 这是我的代码:
addToInput = async val =>{
// console.log('add function');
await this.setState({
input:val
});
await this.picknum();
await this.pickwin();
}
尝试一下!