Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

205
Vistas
React native: setState did not update immediately

I'm trying to make a TicTacToe game for an android app. The TicTacToe's game mode that I'm intended to make is Human-vs-Computer. But the problem is the program did not update the switching-procedure (setState) in my switchPlayer function as the Previous player and Current player is the same after doing the setState. The expected output from switchPlayer function: Previous player: 1, Current player: -1 but the actual output: Previous player: 1, Current player: 1.

I've also tried to use the callback method as suggested/recommended from other Stackoverflow question, but still not working. Am I doing it right? Any suggestion will be much appreciated. Thank you in advance.

Codes are as below:

switchPlayer = (newPlayer) => {
   console.log("Previous player: "+this.state.currentPlayer);
   this.setState(

   {currentPlayer: newPlayer},
   function () {console.log("Current player: "+this.state.currentPlayer); }

   );
};

onTilePress = (row, col, ValidMove) => {

   if (ValidMove == 1) {  //If move is valid

       //Dont allow tiles to change
       var value = this.state.gameState[row][col];
       if (value !== 0) { return;}

       //Identify and grab current player
       var PlayerNow = this.state.currentPlayer;   

       console.log(row, col, PlayerNow);
       //Set the correct tile...
       var arr = this.state.gameState.slice();
       arr[row][col] = PlayerNow;
       this.setState({gameState: arr});

       //Switch to other player
       if (PlayerNow == 1) { //if player 1, then change to bot
           this.switchPlayer(-1);
       }            
       else if (PlayerNow == -1) {
           this.switchPlayer(1);
       }

       console.log("New current player " + this.state.currentPlayer);

       //check winner
       var winner = this.getWinner();  //get the winner update
       if (winner == 1) {
          Alert.alert("Player 1 has won!");
          this.initializeGame();
       }
       else if (winner == -1){
          Alert.alert("Bot has won!");
          this.initializeGame();
       }
       else if (this.checkTie() == 9){ //check if the match is a draw
          Alert.alert("It's a draw!");
          this.initializeGame();
       }
       //Alert.alert("It's Player "+takePlayer+"'s turn!");
       this.BotMove();
   }
   else {
       Alert.alert("Player 1, please make a move!");
   }

}
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

If your problem is that you expected the log statement after the calls to switchPlayer() to already include the state changes... Then you must put everything after your call to switchPlayer in a callback that has been propagated through switchPlayer

switchPlayer = (newPlayer, cb) => {
   console.log("Previous player: "+this.state.currentPlayer);
   this.setState(
       {currentPlayer: newPlayer},
       function () { 
          console.log("Current player: "+this.state.currentPlayer);
          // Callers should put their code 
          if (cb) {
              cb();
          }
       }
   );
};

onTilePress = (row, col, ValidMove) => {
       // Switch to other player
       if (PlayerNow == 1) { //if player 1, then change to bot
           this.switchPlayer(-1, () => {
                // Here, you know the state has been updated
            });
       }            
       else if (PlayerNow == -1) {
             ....
       }
       // This code executes before the state is changed, you get the old state
       // All your code should really be in the callbacks to `switchPlayer`
       // or to any method that calls `setState`
       console.log("New current player " + this.state.currentPlayer);
       ...
}

about 4 years ago · Juan Pablo Isaza Denunciar

0

From React doc:

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

If you want to handle update you could try componentDidUpdate

componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render.

componentDidUpdate(prevProps, prevState) {
  if (this.state.currentUser !== prevState.currentUser) {
    console.log('previous user:', prevState.currentUser);
    console.log('current user:', this.state.currentUser);
  }
}

If you want to just check that something has been updated (without comparison with the previous value), you can use render

render() {
  console.log('current user', this.state.currentUser);
  /* ... */
}

There was one more method componentWillUpdate(nextProps, nextState) where you could compare current and the next state but it's marked as unsafe now, so you shouldn't use it

componentWillUpdate(nextProps, nextState) {
  if (this.state.currentUser !== nextState.currentUser) {
    console.log('current user:', this.state.currentUser);
    console.log('next user:', nextState.currentUser);
  }
}

https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate

One tip that can solve many problems: don't use function(){} as callbacks, use arrow functions instead () => {}, because function(){} has its own this and arrow functions don't have it

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda