¿Es posible llamar a this.setState en la devolución de llamada de this.setState?
Estoy creando una mazmorra de Roguelike y tengo una configuración donde en la devolución de llamada de this.setState se usa una función de ayuda, que llama a this.setState nuevamente. Mi juego se congela en este punto.
Así que tengo un objeto en el componente React que tiene un método para generar un mapa de matriz 2D aleatorio:
this.Dungeon.Generate();Cuando se inicia el juego, llamamos en componentDidMount() a la siguiente función en el componente:
componentDidMount: function() { this.Dungeon.Generate(); this.setState({ board: this.Dungeon.map }, function() { this.generateGamePlay(); }); },this.generateGamePlay() se ve así y básicamente genera y coloca el jugador, el jefe y los elementos al azar en el tablero:
generateGamePlay: function() { var board = this.state.board.slice(); var startPosition = this.randomPosition(); board[startPosition[0]][startPosition[1]] = this.state.player; var bossPosition = this.randomPosition(); board[bossPosition[0]][bossPosition[1]] = this.state.boss[this.state.dungeonLevel]; this.generateWeapons(this.state.dungeonLevel,board); this.generateFood(this.state.dungeonLevel, board); this.generateEnemies(this.state.dungeonLevel, board); this.setState({ board: board }); },Pero cuando un jugador muere, volvemos a llamar arriba para reiniciar el juego:
this.Dungeon.Generate(); //generate a new dungeon map, available in this.Dungeon.map this.setState({ board: this.Dungeon.map, currentMessage: "Game restarted", player: player, weapon: weapon, dungeonLevel: 0 }, function(){ this.generateGamePlay(); })Pero entonces es cuando mi juego se congela. Entonces, la primera vez que llamo a this.generateGamePlay() (que llama a this.setState) funciona, pero la segunda vez se congela. ¿Alguien puede ayudarme?
Vería la parte en la que está configurando this.Dungeon.map en estado.
this.setState({ board: this.Dungeon.map, currentMessage: "Game restarted", player: player, weapon: weapon, dungeonLevel: 0 }, function(){ this.generateGamePlay(); })supongo que algo más puede estar cambiando el objeto del mapa y no usando setstate ya que es una propiedad de Dungeon.
de los documentos de reacción
Nunca modifique this.state directamente, ya que llamar a setState() después puede reemplazar la mutación que realizó. Trate este estado como si fuera inmutable.
cuando pasa la propiedad del mapa a setstate, mantendrá una referencia a this.Dungeon.map que, si lo modifica, causará problemas. Debe hacer una copia de lo que sea .map y pasarla al estado.
También debe hacer que un componente esté a cargo del estado en lugar de llamarlo varias veces en diferentes funciones. De los documentos de reacción
setState() no muta inmediatamente this.state sino que crea una transición de estado pendiente. Acceder a this.state después de llamar a este método puede potencialmente devolver el valor existente.
No hay garantía de funcionamiento síncrono de las llamadas a setState y las llamadas pueden agruparse por lotes para mejorar el rendimiento.
su congelación podría deberse a las condiciones de carrera en el método de renderizado debido a todas las múltiples llamadas setstate.
Como el código de Frank, tengo esto:
this.setState( state => { state.board = this.Dungeon.map return state })Espero que te sea útil, o tal vez lo estoy haciendo mal, o no estoy entendiendo bien tu pregunta.