Javascript 反应状态下的竞争条件

Javascript 反应状态下的竞争条件,javascript,reactjs,race-condition,Javascript,Reactjs,Race Condition,问题: 组件的多个子级几乎同时触发事件。这些事件中的每一个都由handleChange风格的函数处理,这些函数使用React的不变性帮助程序,通过类似于的方式将复杂对象合并到控制组件的状态中 this.setState(React.addons.update(this.state, {$merge: new_value_object})); 当事件独立触发时,这可以正常工作,但当多个事件以这种方式导致状态更新时,每个事件都会从旧版本的状态单独合并。即(psuedo代码,不打算执行) 会产生 {

问题:

组件的多个子级几乎同时触发事件。这些事件中的每一个都由
handleChange
风格的函数处理,这些函数使用React的不变性帮助程序,通过类似于的方式将复杂对象合并到控制组件的状态中

this.setState(React.addons.update(this.state, {$merge: new_value_object}));
当事件独立触发时,这可以正常工作,但当多个事件以这种方式导致状态更新时,每个事件都会从旧版本的状态单独合并。即(psuedo代码,不打算执行)

会产生

{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.state
还是
this.\u synchronous\u state

问题:


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

回答我自己的问题,以防其他人看到这一点

this.setState
可以将函数作为参数,而不是像这样的对象

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

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

为什么要将状态设置为状态更新?直接设置状态:
this.setState({someKey:'someVal'})这解决了您的种族问题,降低了包的大小,并使您的代码更易于阅读。
update
插件用于不可变对象。组件的状态不是不可变对象-它是一个普通的JS对象,可能包含也可能不包含不可变对象。React docs声称该状态应被视为不可变对象。合并是一种从多个源动态设置字段的方法,而不是在一个组件中使用50ish unique
handleChange
函数来处理大量相关的潜在用户输入。然而,它不是一个
不可变的.js
对象。您永远不应该直接修改
this.state
,只能通过
this.setState()
好的,这根本不能回答问题。。。我知道它实际上并不是一成不变的(我的解决方案非常清楚地证明了这一点)。问题是如何更好地处理并发的setState调用。除了那不是真的。。。医生说:上帝,它救了我的大脑。
this.setState(function(state){ 
    ...
    return newState 
});