8

配列をクリアしようとしていますが、問題があります。 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 が Array にプッシュされます。

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

4

3 に答える 3

13

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

最終的な効果は同じです:データが何らかの安定した構成にある場合にのみsetState()UI を更新するため、レンダリング間で複数回呼び出していると思われる場合、それは問題です: すべてのsetState()呼び出しが「最終的に」レンダリングをトリガーする可能性があります。それが起こる前の連続しsetState()た呼び出しは、最初にバインドするのを待たなければ、同じ名前のキー値の更新を「オーバーライド」します。

于 2015-05-01T20:18:22.190 に答える