1

I was following some tutorials on react web-site and tried some example code included. Here's the link for that code in 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>
        );
    }

My question is

console.log

in handleClick method and

console.log

in render method shows 2 different answers. But they should show the same as I can understand because the console.log of handleClick is after set State. Is it because set State takes some time? or any other thing?

Ani Papyan
  • 88
  • 8
StarLord
  • 69
  • 2
  • 11

2 Answers2

1

The setState function is asynchronous. If you want to log after state update, you need to call console.log in the setState callback like this:

this.setState({
    history: history.concat([{
        squares: squares,
    }]),
    stepNumber: history.length,
    xIsNext: !this.state.xIsNext,
}, () => {
    console.log(this.state.history);
});

Hope this helps :)

0

Yes setState function is asynchronous.Don't expect it to run and access the updated value immediately.

state={
  a:1;
}
this.setState({a:a+1})//in some onclick   
console.log(a)//chance of still a=1

To get the updated value do this.

this.setState({a:a+1},()=>{console.log(a)})//prints 2 if initial a=1

The updated value can be accessed inside the callback function which can be given to setState function.

Thakur Karthik
  • 3,034
  • 3
  • 15
  • 24