React setState中的竞争条件

时间:2016-06-28 01:09:12

标签: javascript reactjs race-condition

问题:

组件的多个子节点同时触发事件。这些事件中的每一个都由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);
}

这依赖于直接修改状态。我没有看到运行此代码时出现任何直接问题,它确实解决了手头的问题,但我不得不想象我将继承这个解决方案的大量技术债务。

此解决方案的稍微好一点的版本是;

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.statethis._synchronous_state

问题:

有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:10)

回答我自己的问题以防其他任何人看到这个问题;

|ID| Name| email |apple | lemon | pear | banana | ferrari | mercedes | volvo | BMW | |1 | John| john@doe.com| 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 可以接受一个函数作为它的参数,而不是一个看起来像这样的对象;

this.setState

允许您通过传递给该函数的参数访问当前状态(执行时)。