web-dev-qa-db-ja.com

ReactでsetState()を使用して配列の値を空白/クリアする方法

配列をクリアしようとしていますが、問題が発生しています。 this.setState({warnErrorTypes:[]})

競合状態を扱っているのか、特定の問題が何であるのかはわかりませんが、値を[]にリセットする必要がある場合、配列の値が常に間違っていることがわかります。

[1,2]を含む配列を[]に置き換え、次に[3]に置き換えるにはどうすればよいですか。ここで、次のことが当てはまります。

  1. this.state.warnErrorTypesは、[]で始まる配列です。
  2. 条件に基づいて、2が配列にプッシュされます
  3. 条件に基づいて、1が配列にプッシュされます。
  4. 条件に基づいて、3は配列にプッシュされません
  5. 一時停止します。ユーザーがUIを操作する
  6. 配列が空白になっています:this.setState({warnErrorTypes:[]})
  7. 条件に基づいて、2は配列にプッシュされません
  8. 条件に基づいて、1は配列にプッシュされません
  9. 条件に基づいて、3が配列にプッシュされます。

上記のロジックの結果は、[2,1,3]であると予想される場合、常に[3]になります。

7
JZ.

setStateはアトミックであるため、複数のsetState()呼び出しを発行して動作を期待することはできません。状態が更新されるのを待ってから再度更新するか、インスタンス変数をシャドウイングする必要があります。

オプション1:

_moo: function() {
  this.setState({
    myarr: []
  }, function() { // called by React after the state is updated
    this.setState({
      myarr: [3]
    });
  });
}
_

これはかなり面倒です。もう1つのオプションは、必要なときに状態として送信する「実際の」インスタンス変数を使用することです。

オプション2:

_getInitialState: function() {
  this.mylist = [];
  return {
    myarr: this.mylist
  };
},
...
moo: function() {
  this.mylist = [];
  for(var i=0; i<10; i++) {
    this.mylist.Push(i);
  }
  this.setState({ myarr: this.mylist });
}
_

状態を更新すると、再レンダリングを必要とするコンポーネントの側面が変更されたことを意味するため、配列のクリアと再入力の間など、コンポーネントを再レンダリングする予定がない場合は、setStateを使用しないでください。それを個別に行い、完了したら状態を更新するだけです。

オプション3:

永続的なインスタンス変数を作成せずに、状態値を取得し、更新を実行してから再バインドすることで、これを行うこともできます。

_moo: function() {
  var list = this.state.myarr;
  while(list.length > 0) { list.splice(0,1); }
  for(var i=0; i<10; i++) { list.Push(i); }
  this.setState({ myarr: list });
}
_

正味の効果は同じです:あなたのみデータが安定した構成になっているときにUIを更新するので、レンダリングの間にsetState()を複数回呼び出していると思われる場合は、問題:すべてのsetState()呼び出しがレンダリングをトリガーする可能性があり、最初にバインドされるのを待たないと、連続するsetState()が相互に「オーバーライド」する可能性があります。

これを使用して、setStateを使用せずに配列をクリアすることもできます。

   this.state.your_array.length = 0;
0
leeCoder

Anders Ekdahlが述べたオプション3:

_  moo () {
    this.setState(state => ({
      myarr: []
    }));

    // ...

    if (weShouldAddAThree) {
      this.setState(state => ({
        myarr: [ ...state.myarr, 3 ]   // like Push but without mutation
      }));
    }
  }
_

このパターンは、状態の更新を実行するときに以前の既存の状態を参照する必要がある場合に役立ちます。例で前の状態が本当に必要かどうかはわかりませんが、必要な場合と同じようにこのパターンを説明します。

setStateに提供するマージ操作は、将来のある時点で常に非同期に適用されます Reactの裁量でsetState()関数が戻ったとき、操作は適用されておらず、キューに入れられているだけです。

したがって、状態アップデーターで_this.state_を使用しないでください。これは、状態の古いコピーである古いコピーである可能性があるためです。以前の状態を知る必要がある場合は、setStateに渡す関数でstate引数を受け取り、それを使用する必要があります。

0
joeytwiddle