我正在React网站上关注一些教程,并尝试了一些示例代码。这是Codepen中该代码的链接
https://codepen.io/gaearon/pen/gWWZgR?editors=0010
handleClick(i) {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
history: history.concat([{
squares: squares,
}]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext,
});
console.log(this.state.history);
}
render() {
console.log(this.state.history);
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
const moves = history.map((val, index) => {
const desc = index ? 'Go to move #' + index : 'Go to game start';
return (
<li key={index}>
<button onClick={() => this.jumpTo(index)}>{desc}</button>
</li>
);
});
let status;
if (winner) {
status = 'Winner: ' + winner;
} else {
status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<div className="game">
<div className="game-board">
<Board
squares={current.squares}
onClick={(i) => this.handleClick(i)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
);
}
我的问题是
console.log
在handleClick方法和
渲染方法中的console.log
显示2个不同的答案。但是它们应该显示出与我所能理解的相同的内容,因为handleClick的console.log位于set State之后。是否因为设定状态需要一些时间?还是其他东西?
答案 0 :(得分:1)
setState函数是异步的。如果要在状态更新后记录日志,则需要像这样在setState回调中调用console.log:
this.setState({
history: history.concat([{
squares: squares,
}]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext,
}, () => {
console.log(this.state.history);
});
希望这会有所帮助:)
答案 1 :(得分:0)
是的setState函数是异步的。不要期望它运行并立即访问更新的值。
state={
a:1;
}
this.setState({a:a+1})//in some onclick
console.log(a)//chance of still a=1
要获取更新的值,请执行此操作。
this.setState({a:a+1},()=>{console.log(a)})//prints 2 if initial a=1
可以在回调函数内部访问更新后的值,该回调函数可以提供给setState函数。