setState是否需要一些时间来执行?

时间:2018-11-06 19:44:05

标签: javascript reactjs ecmascript-6

我正在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之后。是否因为设定状态需要一些时间?还是其他东西?

2 个答案:

答案 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函数。