React, 2 setstate in same function: second one erase the first

时间:2018-06-01 17:35:53

标签: reactjs setstate

I am trying to run the code above but the state get updated only for idx. From what i understand the second function's setState will not get the updated state and thats why this happens. Is there a way to make it work properly (expect than merge the 2 functions in one)

doIt(idx,array) {
   this.doFirst(array);
   this.doSecond(idx);
}

doFirst(array){
   //bla bla bla code
   this.setState(test: {...this.state.test, array});
}

doSecond(idx) {
    // bla bla bla code
    this.setState(test: {...this.state.test, idx});
}

5 个答案:

答案 0 :(得分:3)

setState()是异步的。

  

将setState()视为请求而不是立即命令   更新组件。为了获得更好的感知性能,React可能会   延迟它,然后一次更新几个组件。应对   并不保证立即应用状态变化。

它需要一个可选的回调函数,该函数将在setState完成并重新呈现组件后执行。你可以使用那个回调。

如果下一个状态取决于之前的状态,建议使用更新程序功能形式 setState(更新程序[,回调])

doIt(idx,array) {
   this.doFirst(array, () => this.doSecond(idx));
}

doFirst(array, callback){
   //bla bla bla code
   this.setState(firstUpdaterFunction, callback);
}

doSecond(idx) {
    // bla bla bla code
    this.setState(2ndUpdaterFunction);
}

参考文献:

https://reactjs.org/docs/react-component.html#setstate

https://stackoverflow.com/a/41446620/2073920

答案 1 :(得分:1)

下面两个声明同时执行。

this.doFirst(array);
this.doSecond(idx);

这两个人都在呼叫setStatesetState is asynchronous。因此,无法保证值将按顺序更新。 由于这场比赛,这个价值被覆盖了。 更好地链接这些电话。

doIt(idx,array) {
   this.doFirst(array);   
}

doFirst(array){
   //bla bla bla code
   this.setState({test: {...this.state.test, array}},()=>{

    this.doSecond(idx); 
   });
}

doSecond(idx) { 
    this.setState({test: {...this.state.test, idx}});
}

答案 2 :(得分:0)

很难说清楚,因为您的示例setState调用不是正确的this.setState(test: {...this.state.test, idx});。你的意思是你在做this.setState({test: {...this.state.test, idx}});吗?如果是这样,你应该使用回调而不是像这样的对象:

this.setState(() => ({ test: {...this.state.test, idx}})

答案 3 :(得分:0)

我假设您只是错误地放置了状态对象周围的括号,所以我添加了这些。

无论如何,您想要使用更新程序功能:

this.setState((prevState, props) => ({test: {...prevState.test, array}});

请注意,这可能不是您想要的,因为它在ES 2015中转换为: this.setState((prevState, props) => ({test: {...prevState.test, array: array}});

你也希望为其他功能做同样的事情。 React批处理将状态调用设置在一起,因此如果您不使用更新程序,则有可能您将为连续的函数调用访问陈旧状态。这可能就是在这种情况下发生的事情。

答案 4 :(得分:0)

正如其他人已经指出的那样,echo "<label style='padding:5px;' id='".>$rowmain1[$i]."' myattr="value">$rowmain1[$i]</label><br>"; <script type="text/javascript"> $(document).on('ready', function(){ $('select').on('change', function() { var selectValue = $(this).val(); console.log(selectValue); var valueTicket = $("#my_id").attr("myattr"); console.log(valueTicket); var mutiplyvalue = valueTicket * selectValue; console.log(mutiplyvalue); }); }); </script> 是异步的。如果你需要使用以前的状态,我想指出setState的第一个参数是setState,它可以采用一个函数来计算前一个状态的下一个状态:

updater