【问题标题】:React, 2 setstate in same function: second one erase the firstReact,相同功能中的 2 个 setstate:第二个擦除第一个
【发布时间】:2018-06-01 17:35:53
【问题描述】:

我正在尝试运行上面的代码,但状态仅针对 idx 进行更新。据我了解,第二个函数的 setState 不会获得更新的状态,这就是发生这种情况的原因。有没有办法让它正常工作(期望将两个功能合并为一个)

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});
}

【问题讨论】:

标签: reactjs setstate


【解决方案1】:

setState() 是异步的。

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

它需要一个可选的回调函数,一旦 setState 完成并重新渲染组件,就会执行该回调函数。您可以使用该回调。

如果下一个状态依赖于上一个状态,建议使用updater函数形式setState(updater[, callback])

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

【讨论】:

    【解决方案2】:

    下面两条语句同时执行。

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

    这两个都调用setState.setState 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}});
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        无论如何,您都想使用更新函数:

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

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

        您也希望对其他功能执行相同的操作。 React 批处理将状态调用设置在一起,因此,如果您不使用更新程序,您可能会为后续的函数调用访问陈旧状态。这可能就是这种情况下发生的情况。

        【讨论】:

          【解决方案5】:

          正如其他人已经指出的那样,setState 是异步的。如果你需要使用前一个状态我想指出setState的第一个参数是updater,它可以带一个函数从前一个状态计算下一个状态:

          doFirst(array){
             this.setState(previousState => ({ test: {...previousState.test, array} }));
          }
          
          doSecond(idx) {
              this.setState(previousState => ({ test: {...previousState.test, idx} }));
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-01-01
            相关资源
            最近更新 更多