我很难解决我的问题所在,我有一个反应组件,它调用从它的父母传入的函数作为道具。该函数正在按预期执行。但是,在该功能中,我想在父母上调用第二个函数两次,每次更新状态。由于某种原因,调用之间不会更新状态。这是一个非常简单的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()
。移动是一个简单的整数,它是要考虑的移动的数组索引。
答案 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)));
}
现在第二个状态更新总是在第一个之后执行。