【发布时间】:2021-07-17 22:57:56
【问题描述】:
我非常精通 JavaScript,但正在学习 React。我正在尝试做井字游戏。当我获得胜利时,我希望 this.state.message 立即更新,this.state.done 立即更改为 true,并且 this.state.turn 不更改。目前我已经弄清楚了其中的一些,但没有弄清楚 this.state.turn 的变化。它说错误的玩家获胜。我知道 setState 是异步的,这就是为什么我无法一起更新这些东西,我通过回调修复了其中一些,但我正在尝试找到更好的方法并更好地理解所有内容。
class Board extends Component {
constructor(props) {
super(props);
this.state = {
board: ['', '', '', '', '', '', '', '', ''],
turn: 'O',
message: 'O goes',
done: false
}
}
addItem(x) {
if (this.state.done === true) {
this.setState({message: this.state.turn + ' wins'});
return;
}
let array = [...this.state.board];
if (array[x] !== "") {
return;
}
array[x] = this.state.turn;
this.setState({board: array}, () => {
this.checkWinners(0, 1, 2);
this.checkWinners(3, 4, 5);
this.checkWinners(6, 7, 8);
this.checkWinners(0, 3, 6);
this.checkWinners(1, 4, 7);
this.checkWinners(2, 5, 8);
this.checkWinners(0, 4, 8);
this.checkWinners(2, 4, 6);
if (this.state.done === false) {
this.setState({turn: (this.state.turn === "X") ? "O" : "X"});
this.setState({message: (this.state.message === "X goes") ? "O goes" : "X goes"});
}
});
}
checkWinners(a, b, c) {
if ((this.state.board[a] === "X"
&&
this.state.board[b] === "X"
&&
this.state.board[c] === "X")
||
(this.state.board[a] === "O"
&&
this.state.board[b] === "O"
&&
this.state.board[c] === "O"
)
) {
this.setState({done: true}, () => {
console.log('Winner');
this.setState({message: this.state.turn + ' wins'});
});
}
}
render() {
return (
<>
<h1>Tic-Tac-Toe</h1>
<h2>{this.state.message}</h2>
<div className="board">
{this.state.board.map((item, index) => (
<div className="boxes" key={index} onClick={() => this.addItem(index)}>{this.state.board[index]}</div>
))}
</div>
</>
)
}
}
【问题讨论】:
-
更新后不要直接读取状态。设置状态是异步的。你不能指望它马上是最新的
-
@evolutionxbox 感谢您的回答。也许我应该问一个不同的问题。我知道设置状态是异步的,但我想知道如何在同一个 onClick 中更改所有这些内容,因为如果有人获胜,我希望游戏在他们采取行动后立即告诉他们。
-
不要多次调用
setState(),而是先收集更改,然后再调用一次。 -
@RoboRobok 谢谢。我仍然不明白的是,过牌赢家取决于董事会的状态,然后更新或不更新转牌的状态取决于过牌赢家。我不明白如何将这些放在一起。
-
我想说的是,您基于该行的
checkWinners()方法的设计相当糟糕。它应该自己检查所有可能性,并且仅在必要时继续。一般来说,通常在 React 中,中间有这个状态是不错的,因为它只影响 UI,并且有一个渲染周期作为中间状态通常很好。
标签: javascript reactjs asynchronous setstate