javascript - react : async setState updates to late

标签 javascript reactjs npm frontend

我正在学习 React.js,并尝试开发一个简单的格斗游戏。

我尝试更新状态(下面的代码)来定义轮到谁:

this.setState({ whoseRound: rand }, () => {
    console.log(this.state.whoseRound)
})

然后,我开始一个 while 循环。在我的循环中,我想知道要攻击谁的回合,使用之前发起的状态 whoseRound

我的问题是:由于函数setState是异步的,当我开始循环时,我的状态值仍然为“0”。显然,我的 runRound() 方法的结尾也有同样的问题。

我该如何正确解决该问题?

谢谢大家。

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      characters: [], //contains Array of characters objects
      readyToFight: false, // character selected or not
      firstPlayerCharacter: null, //contains key of character on select
      secndPlayerCharacter: null, //contains key of character on select
      whoseRound: 0 // defines whose character attacks
    }
  }

  //Run the fight
  setFight = () => {
    let firstFighter = this.state.characters[this.state.firstPlayerCharacter]
    let secndFighter = this.state.characters[this.state.secndPlayerCharacter]

    this.initiateFight(firstFighter, secndFighter);
  }

  //initiate fight rounds
  initiateFight = (firstFighter, secndFighter) => {

    // set who attacks first randomly => returns 1 or 2
    var rand = randomDice(1, 2)
    this.setState({whoseRound: rand}, () => {console.log('test:' + this.state.whoseRound)})

    while(firstFighter.stats.health > 0 || secndFighter.stats.healthh > 0){
      /* !!! depending on whoseRound is, we set an attacker 
    and a defenser !!! My probleme is that 
    this.state.whoseRound's value is 0 
    at this moment, as the sateState 
    method is async. */
      1 === this.state.whoseRound ? this.runRound(firstFighter, secndFighter) : this.runRound(secndFighter, firstFighter)
    }
  }

  // Lance les actions définies pour un round
  runRound = (attacker, defender) => {
    let hit = false
    let cc = false
    let damages

    hit = randomDice(0, 100) <= this.getHitChances(attacker, defender)
    cc = randomDice(0, 100) <= this.getCriticalChances(attacker, defender)
    damages = this.getDamages(attacker, defender, cc)

    if(hit)
    {
      //console.log(attacker.name + ' attaque ' + defender.name + ' et lui occtroie ' + damages + ' points de dégats')
      //console.log('les points de vie de ' + defender.name + ' passent de ' + defender.stats.health + ' à ' + (defender.stats.health - damages))
      defender.stats.health -= damages
    }

    //Now, it's the other character's turn
    1 === this.state.whoseRound ? this.setState({whoseRound: 2}) : this.setState({whoseRound: 1})

  }
  
}

export default App;

最佳答案

您可以做两件简单的事情,

首先:setState回调中执行您想要执行的任何操作

this.setState({whoseRound: rand}, () => {
     console.log('test:' + this.state.whoseRound)
     while(firstFighter.stats.health > 0 || secndFighter.stats.healthh > 0){
      /* !!! depending on whoseRound is, we set an attacker 
    and a defenser !!! My probleme is that 
    this.state.whoseRound's value is 0 
    at this moment, as the sateState 
    method is async. */
      1 === this.state.whoseRound ? this.runRound(firstFighter, secndFighter) : this.runRound(secndFighter, firstFighter)
    }
})

第二:不要使用state,而是使用rand,因为这就是您要更新状态的内容

while(firstFighter.stats.health > 0 || secndFighter.stats.healthh > 0){
      /* !!! depending on whoseRound is, we set an attacker 
    and a defenser !!! My probleme is that 
    this.state.whoseRound's value is 0 
    at this moment, as the sateState 
    method is async. */
      1 === rand ? this.runRound(firstFighter, secndFighter) : this.runRound(secndFighter, firstFighter)
    }

关于javascript - react : async setState updates to late,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46733624/

相关文章:

javascript - 模式匹配永远不会终止

javascript - 访问集合中的第二个项目[ map ]

javascript - 如何在网页中存储值(字符串)

javascript - 如何在内存中正确存储访问 token react

javascript - 删除字符串中倒数第二个正斜杠之后的数据

javascript - 与 Node 服务器一起使用时,webpack 创建的bundle.js 未加载

javascript - 占位符图像无法通过卡片正确加载 [ReactJs]

node.js - NPM Start – 权限错误

ios - 无法在 Cordova 5.0.0 中添加或构建 ios 平台

node.js - Node 。并且 npm start 不起作用