Search code examples
javascriptreactjstic-tac-toesetstate

Why does state not update as expected?


I am currently building a TicTacToe game and would like to store my current player in state as currentPlayer. After one player moves, I update currentPlayer to the opposite player. However, when I try to log the new state to the console, it's not producing the value of the updated state.

Here is my code:

state = {
    currentPlayer: 'X',
}

// This function is triggered by an onClick attribute.
// It first finds the html element and renders the currentPlayer value from state.
// It then switchs the value of currentPlayer from X to O and calls setState to update the state.
// Why does the console.log not show the updated state value?

userDidMove = () => {
    document.getElementById('cell').innerHTML = this.state.currentPlayer
    let nextPlayer = this.state.currentPlayer === 'X' ? 'O' : 'X'
    this.setState({ 
        currentPlayer: nextPlayer,
    })
    console.log ('userDidMove changed state with ',this.state.currentPlayer)
}

Any help figuring out how to get this function to return the updated state value would be great!


Solution

  • State changes are asynchronous. When your new state is dependent on the previous state, use the state updater function instead.

    When the state changes are committed you can use the callback which will have the updated state.

    this.setState((previousState) => {
      const nextPlayer = previousState.currentPlayer === 'X' ? 'O' : 'X';
    
      return {
        currentPlayer: nextPlayer
      }
    }, () => {
      // your updated state related code here
    
      console.log('userDidMove changed state with ', this.state.currentPlayer)
    });
    

    this.setState(updatedFunc, callback);