2016-06-28 5 views
4

問題に反応:コンポーネントのレースコンディションでSETSTATE

複数の子供たちはイベントが同時に近くトリガー持っています。これらのイベントのそれぞれはhandleChangeによって処理され、Reactの不変性ヘルパーを使用して複雑なオブジェクトを制御コンポーネントの状態にマージするスタイル関数です。

this.setState(React.addons.update(this.state, {$merge: new_value_object})); 

イベントが独立してトリガするとき、これは正常に動作しますが、複数のイベントが、このように状態への更新を引き起こしたときに、それぞれが個別に状態の古いバージョンからマージされます。私。 (擬似コード、実行するつもりはない)。

function logState() { console.log(this.state) } 

logState(); // {foo: '', bar: ''} 

var next_value_object_A = {foo: '??'} 
var next_value_object_B = {bar: '!!'} 

this.setState(React.addons.update(this.state, {$merge: new_value_object_A}), 
    logState); 
this.setState(React.addons.update(this.state, {$merge: new_value_object_B}), 
    logState); 

;

{foo: '??', bar: ''} 
{foo: '', bar: '!!'} 
私が使用したくない

ひどいソリューション:以下

が動作しているようですが、また、主要アンチパターンのようです。

setSynchronousState: function(nextState){ 
    this.state = React.addons.update(this.state, {$merge: nextState}); 
    this.setState(this.state); 
} 

これは、状態を直接変更することに依存します。私はこのコードを実行する上で直ちに問題が発生するとは思わないし、手元にある問題を解決していますが、私はこの解決策で大規模な技術的負債を継承していると想像しなければなりません。

このソリューションのやや優れたバージョンは次のとおりです。

成功した今、私たちはアプリケーションの周りに渡される矛盾する情報の問題を持っているものの、直接 this.stateに触れる回避
getInitialState: function(){ 
    this._synchronous_state = //Something 
    return this._synchronous_state; 
}, 

_synchronous_state: {}, 

setSynchronousState: function(nextState){ 
    this._synchronous_state = React.addons.update(this._synchronous_state, {$merge: nextState}); 
    this.setState(this._synchronous_state); 
} 

。現在、他の機能は、this.stateまたはthis._synchronous_stateにアクセスしているかどうかに妥協する必要があります。

質問:この問題を解決するためのより良い方法が

ありますか?

+1

なぜ状態を状態の更新として設定していますか?状態を直接設定するだけです: 'this.setState({someKey: 'someVal'});これはレースの問題を解決し、パッケージのサイズを小さくし、コードを読みやすくします。 'update'アドオンは、不変オブジェクトに使われることを意図しています。コンポーネントの状態は不変オブジェクトではありません。通常のJSオブジェクトであり、不変オブジェクトを含む場合と含まない場合があります。 –

+0

React docsは、状態を不変オブジェクトとして扱うべきだと主張しています。マージは、関連する多数の潜在的なユーザ入力を処理するために、あるコンポーネントに一意の 'handleChange'関数を持たせるのではなく、複数のソースからフィールドを動的に設定する手段として行われています。 – gravityplanx

+0

*のキーワードが*考えられます。しかし、 'immutable.js'オブジェクトではありません。 'this.state'を' this.setState() 'で直接変更するべきではありません。 –

答えて

7

誰かがこれを見た場合に自分の質問に答える。

this.setStateは、このように見えるオブジェクトではなく、その引数として機能することができます。

this.setState(function(state){ 
    ... 
    return newState 
}); 

これは、(実行時に)その関数に渡された引数を使って現在の状態にアクセスできるようにします。

関連する問題