React似乎同时执行两个功能

时间:2019-04-10 03:01:07

标签: javascript reactjs

我做了一个简单的剪刀石头布游戏。在onclick期间,我调用一个函数以添加数字并更改状态。然后,在该函数中,我再调用2个函数,其中一个从1到3之间选择一个随机数,并将其转换为石头/纸/剪刀,然后将其分配给状态,然后另一个函数找出谁赢了:

addToInput = val =>{
    this.setState({ 
        input:val
    });

    this.picknum();
    this.pickwin();       
}

https://codepen.io/russiandobby/pen/xeRYzw?editors=0002

起初我以为picknumpickwin将同时执行,但是即使我尝试在pickwin中调用picknum,它仍然不会工作。

似乎发生的事情是,当执行pickwin时,它看起来是一个旧状态,而不是被picknum改变的状态。

如何解决此问题?

3 个答案:

答案 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();

 } 

尝试一下!