简体   繁体   English

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

[英]Using this.setState in the callback of this.setState in React JS?

Is it possible to call this.setState in the callback of this.setState? 是否可以在this.setState的回调中调用this.setState?

I am making a Roguelike Dungeon and have a setup where in the callback of this.setState a helper function is used, that calls this.setState again. 我正在制作一个Roguelike Dungeon并且有一个设置,在this.setState的回调中使用了一个辅助函数,它再次调用this.setState。 My game freezes at this point. 我的游戏冻结了。

So I have an object in the React component that has a method to generate a random 2D array map: 所以我在React组件中有一个对象,它有一个生成随机2D数组映射的方法:

this.Dungeon.Generate();

When the game starts, we call in componentDidMount() the following function in the component: 当游戏开始时,我们在componentDidMount()中调用组件中的以下函数:

componentDidMount: function() {

    this.Dungeon.Generate();

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

      this.generateGamePlay();

    });

  },

this.generateGamePlay() looks like this and basically generates and places the player, boss and items randomly on the board: this.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
});

 },

But when a player dies, we call above again to reset the game: 但是当玩家死亡时,我们再次呼叫以重置游戏:

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

          })

But then is when my game freezes. 但是当我的游戏冻结时。 So the first time I call this.generateGamePlay() (which calls this.setState) it works but the second time it freezes. 所以我第一次调用this.generateGamePlay()(调用this.setState)它可以工作,但第二次冻结。 Anyone can help me? 有人可以帮帮我吗?

I would look at the part where you are setting this.Dungeon.map in state. 我会看看你正在设置this.Dungeon.map状态的部分。

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

                this.generateGamePlay();

          })

my guess is that something else may be changing the map object and not using setstate since it is a property of the Dungeon. 我的猜测是其他东西可能正在改变地图对象而不是使用setstate,因为它是Dungeon的属性。

from the react docs 来自反应文档

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. 永远不要直接改变this.state,因为之后调用setState()可能会替换你所做的突变。 Treat this.state as if it were immutable. 把this.state看作是不可变的。

when you pass the map property to setstate it will keep a reference to this.Dungeon.map which if you then modify will cause issues. 当你将map属性传递给setstate时,它将保留对this.Dungeon.map的引用,如果你随后修改将导致问题。 You should make a copy of what ever .map is and pass that to state. 你应该复制.map的副本并将其传递给state。

You should also make one component in charge of the state instead of calling it multiple times in different functions. 您还应该制作一个负责状态的组件,而不是在不同的功能中多次调用它。 From the react docs 来自反应文档

setState() does not immediately mutate this.state but creates a pending state transition. setState()不会立即改变this.state,但会创建挂起状态转换。 Accessing this.state after calling this method can potentially return the existing value. 调用此方法后访问this.state可能会返回现有值。

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains. 无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以提高性能。

your freezing could be from race conditions in the render method due to all the multiple setstate calls. 由于所有多个setstate调用,你的冻结可能来自render方法中的竞争条件。

Like Frank's code I have this: 就像弗兰克的代码一样,我有这个:

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

I hope It would be handy for you, or maybe I'm doing it wrong, or misunderstanding your question 我希望这对你来说很方便,或者说我做错了,或者误解了你的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM