2017-08-16 58 views
1

我有一个窗体与多个控件,将所有内容保存到一个变量。每个控件都有一个onChanged功能,它运行与控制的新值的状态更新:如何链接状态更新?

function onChangedValUpdate(newVal){ 
    let fields = clone(this.state.fields); 
    fields[controlId] = newVal; 
    this.setState({fields}); 
} 

我的控件是动态创建的,而当他们跑了,在他们的初始值运行onChangedValUpdate,如果存在。问题是,有时会同时创建很多控件,并且React会使用同一个克隆的fields对象为每个更新排队其setState。该对象不会在setState之间更新,推测可能是由于类似的原因到this question.这意味着,除了一个控件的更新之外,其他所有更新都会被覆盖。

我试着写过智能例程用来setState的回调只是运行它,如果没有一个已在进行中,并记得在setState S之间的fields变量所做的更改,但反应就去跑所有我同时排队更新。无论如何,这个例程让人觉得太正确了。

我敢肯定这是一个微不足道的问题,但我似乎无法用Googleable的方式来制定我的问题。如何链接同时发生的状态更新,其中可能有任何数字?

编辑对于后人,我的解决方案,这要归功于尤里:

function onChangedValUpdate(newVal){ 
    this.setState(state => { 
    let fields = clone(state.fields); 
    fields[controlId] = newVal; 
    return {fields}; 
    } 
} 

回答

2

你可以传递一个突变功能setState。这将防止覆盖更新批处理,因为每个回调将获得最近的以前的状态。

function onChangedValUpdate(newVal){ 
    this.setState(function(state){ 
    const fields = clone(state.fields) 

    fields[controlId] = newVal 

    return {fields: fields} 
    }); 
} 

或者使用对象扩展和增强对象文字。

function onChangedValUpdate(newVal){ 
    this.setState(({fields}) => ({fields: {...fields, [controlId]: newVal}})); 
} 
+0

非常好,谢谢。我不知道我可以做到这一点。我在'setState'内部封装了我的函数,并克隆了它的传递状态对象以进行突变。现在所有的控件都是按照他们应该写的。 –