更新状态

时间:2016-09-09 08:17:59

标签: javascript reactjs

我很难解决我的问题所在,我有一个反应组件,它调用从它的父母传入的函数作为道具。该函数正在按预期执行。但是,在该功能中,我想在父母上调用第二个函数两次,每次更新状态。由于某种原因,调用之间不会更新状态。这是一个非常简单的tic-tac-toe应用程序,我尝试接受用户移动(点击子组件),让玩家移动然后放置AI的移动。然后让玩家点击另一个空心方块。

以下是相关代码:

updateBoard(loc) {
    if(this.state.gameBoard[loc] === 'x' || this.state.gameBoard[loc]=== 'o'    || this.state.winner !== null){
      //invalid move
      return;
    }
    let currentGameBoard = this.state.gameBoard;
    currentGameBoard.splice(loc, 1, this.state.turn);
      //Check if there is a winner or draw
      if (this.winner(currentGameBoard, this.state.turn)){
       this.setState({gameBoard: currentGameBoard, winner: this.state.turn});
       return;
     } else if(this.tie(currentGameBoard)) {
       //Make game over component visible
       this.setState({gameBoard: currentGameBoard, winner: 'd'});
       return;
     }
     this.setState({gameBoard: currentGameBoard, turn: this.state.turn === 'x' ? 'o' : 'x'});
   }

   gameLoop(move){
     this.updateBoard(move);
     this.updateBoard(this.findAiMove(this.state.gameBoard));
   }

由于某种原因,第一次移动正确发生。第一个X放置在玩家点击的任何地方,但AI移动根本不会发生。在棋盘上额外点击将放置2点,然后是2点和2点,直到比赛结束。玩家点击gameLoop(),然后在玩家移动和AI移动时调用updateBoard()。移动是一个简单的整数,它是要考虑的移动的数组索引。

1 个答案:

答案 0 :(得分:0)

setState是异步的,所以不能保证状态会在连续的调用之间更新。

这意味着如果您将updateBoard方法调用两次,则第二次调用时状态可能没有及时从第一次调用更新以读取新值。

解决问题的一种方法是使用setState的回调参数,一旦状态更新就会触发:

updateBoard(loc, callback) {
    if(this.state.gameBoard[loc] === 'x' || this.state.gameBoard[loc]=== 'o'    || this.state.winner !== null){
      //invalid move
      return;
    }
    let currentGameBoard = this.state.gameBoard;
    currentGameBoard.splice(loc, 1, this.state.turn);
    let stateUpdate;
      //Check if there is a winner or draw
      if (this.winner(currentGameBoard, this.state.turn)){
       stateUpdate = { gameBoard: currentGameBoard, winner: this.state.turn };
     } else if(this.tie(currentGameBoard)) {
       //Make game over component visible
       stateUpdate = { gameBoard: currentGameBoard, winner: 'd'};
     } else {
       stateUpdate = { gameBoard: currentGameBoard, turn: this.state.turn === 'x' ? 'o' : 'x'};
     }

     this.setState(stateUpdate, callback);
   }

   gameLoop(move){
     this.updateBoard(move, () => this.updateBoard(this.findAiMove(this.state.gameBoard)));
   }

现在第二个状态更新总是在第一个之后执行。