在 React JS 中 this.setState 的回调中使用 this.setState?

Using this.setState in the callback of this.setState in React JS?

是否可以在this.setState的回调中调用this.setState?

我正在制作一个 Roguelike Dungeon 并有一个设置,其中在 this.setState 的回调中使用了一个辅助函数,它再次调用 this.setState。我的游戏此时卡住了。

所以我在 React 组件中有一个对象,它有一个生成随机二维数组映射的方法:

this.Dungeon.Generate();

游戏开始时,我们在componentDidMount()中调用组件中的如下函数:

componentDidMount: function() {

    this.Dungeon.Generate();

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

      this.generateGamePlay();

    });

  },

this.generateGamePlay() 看起来像这样,基本上生成玩家、boss 和物品并将其随机放置在棋盘上:

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

          })

但那时我的游戏就卡住了。所以我第一次调用 this.generateGamePlay() (它调用 this.setState)它工作但第二次它冻结了。谁能帮帮我?

我会查看您在状态中设置 this.Dungeon.map 的部分。

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

                this.generateGamePlay();

          })

我的猜测是其他东西可能正在更改地图对象而不是使用 setstate,因为它是 Dungeon 的 属性。

来自 react docs

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

当您将映射 属性 传递给 setstate 时,它​​会保留对 this.Dungeon.map 的引用,如果您随后修改该引用将会导致问题。您应该复制 .map 的内容并将其传递给 state。

你也应该让一个组件负责状态,而不是在不同的函数中多次调用它。来自 react docs

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

您的冻结可能是由于所有多个 setstate 调用导致渲染方法中的竞争条件。

就像 Frank 的代码一样,我有这个:

this.setState( state => {
  state.board = this.Dungeon.map
  return state
})

希望对你有用,或者我做错了,或者误解了你的问题