Используя это.setState в обратном вызове этого.setState в React JS?


Можно ли это назвать.setState в обратном вызове этого.выполнении функция setState?

Я делаю roguelike подземелье и есть установка, где в обратном вызове этого.setState используется вспомогательная функция, которая вызывает это.снова выполнении функция setState. В этот момент моя игра замирает.

Итак, у меня есть объект в компоненте React, который имеет метод для генерации случайной 2D-карты массива:

this.Dungeon.Generate();

Когда игра начинается, мы вызываем в componentDidMount () следующую функцию в компонент:

componentDidMount: function() {

    this.Dungeon.Generate();

    this.setState({
      board: this.Dungeon.map
    }, function() {

      this.generateGamePlay();

    });

  },

Это.generateGamePlay() выглядит следующим образом и в основном генерирует и размещает игрока, босса и предметы случайным образом на доске:

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
});

 },

Но когда игрок умирает, мы снова вызываем выше, чтобы сбросить игру:

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();

          })

Но тогда моя игра замирает. Так что в первый раз я это называю.generateGamePlay () (который вызывает это.setState) он работает, но во второй раз он зависает. Кто-нибудь может мне помочь?

1 5

1 ответ:

Я бы посмотрел на ту часть, где вы это устанавливаете.Темница.карта в штате.

this.setState({
          board: this.Dungeon.map, currentMessage: "Game restarted", player: player, weapon: weapon, dungeonLevel: 0
          }, function(){

                this.generateGamePlay();

          })

Я предполагаю, что что-то еще может изменять объект карты и не использовать setstate, так как это свойство подземелья.

Из react docs

Никогда не мутируйте это.состояние непосредственно, так как вызов setState () впоследствии может замените мутацию, которую вы сделали. Лечи это.состояние, как если бы это было неизменный.

При передаче свойства map в setstate оно будет держать ссылку на это.Темница.карта, которая, если вы затем измените, вызовет проблемы. Вы должны сделать копию того, что когда-либо .карта есть и передайте ее государству.

Вы также должны сделать один компонент ответственным за состояние, а не вызывать его несколько раз в разных функциях. Из react docs

SetState() не изменяет это сразу.государство, но создает в ожидании перехода в другое состояние. Доступ к этому.состояние после вызова этого метод может потенциально возвращает существующее значение.

Нет никакой гарантии синхронной работы вызовов setState и вызовы могут быть пакетированы для повышения производительности.

Ваша заморозка может быть вызвана условиями гонки в методе render из-за всех многочисленных вызовов setstate.