web-dev-qa-db-ja.com

this.setStateのコールバックでthis.setStateを使用React JS?

This.setStateのコールバックでthis.setStateを呼び出すことは可能ですか?

私はローグライクダンジョンを作成しており、this.setStateのコールバックで、this.setStateを再度呼び出すヘルパー関数が使用される設定があります。この時点でゲームがフリーズします。

したがって、Reactコンポーネントにオブジェクトがあり、ランダムな2D配列マップを生成するメソッドがあります。

this.Dungeon.Generate();

ゲームが開始したら、componentDidMount()でコンポーネントの次の関数を呼び出します。

componentDidMount: function() {

    this.Dungeon.Generate();

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

      this.generateGamePlay();

    });

  },

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

 },

ただし、プレイヤーが死亡した場合は、上記を再度呼び出してゲームをリセットします。

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を呼び出す)を呼び出すと機能しますが、2回目にはフリーズします。誰でも手伝ってくれる?

12
chemook78

状態でthis.Dungeon.mapを設定している部分を確認します。

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

                this.generateGamePlay();

          })

私の推測では、それはDungeonのプロパティであるため、マップオブジェクトを変更し、setstateを使用していない可能性があります。

反応ドキュメント から

This.stateを直接変更しないでください。後でsetState()を呼び出すと、行った変更が置き換えられる可能性があります。 this.stateを不変であるかのように扱います。

setstateにmapプロパティを渡すと、this.Dungeon.mapへの参照が保持され、変更すると問題が発生します。これまでの.mapのコピーを作成し、それを状態に渡す必要があります。

異なる関数で複数回呼び出すのではなく、状態を管理する1つのコンポーネントを作成する必要もあります。 react docs から

setState()はthis.stateをすぐには変更しませんが、保留中の状態遷移を作成します。このメソッドを呼び出した後でthis.stateにアクセスすると、既存の値が返される可能性があります。

SetStateの呼び出しの同期操作の保証はなく、パフォーマンスを向上させるために呼び出しをバッチ処理することができます。

複数のすべてのsetstate呼び出しが原因で、renderメソッドの競合状態が原因でフリーズする可能性があります。

2
Frank

フランクのコードのように、私はこれを持っています:

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

私はそれがあなたにとって便利であることを願っています、または多分私はそれを間違っている、またはあなたの質問を誤解している

0
G33kTony