如何在react中同步更新状态

IT技术 reactjs axios setstate
2021-05-16 06:19:42
onSave=()=>{
    if (this.state.intialValue<=0) {
        this.setState({errorIntialValue: true})
      }
      else
      {
      this.setState({errorIntialValue: false})
      }
      if (this.state.age>=25|| this.state.age<=-1) {
        this.setState({errorAge: true})
      }
      else{
        this.setState({errorAge: false})
      }
      if (this.state.rollNo<0) {
        this.setState({errorRollno: true})
      }
      else{
        this.setState({errorRollno: false})
      }
       if(!(this.state.errorIntialValue|| this.state.errorAge ||errorRollno)){    //have to 
                                                                    enter only if no error
    let newData={
            intialValue:this.state.intialValue,
            age:this.state.age,
            rollNo:this.state.rollNo
    }
    this.props.updateData(newData)
}

我有一个 onClick 事件 onSave。如果出现错误,我将它们的状态设置为 true。由于 SetState 是异步的,因此该值不会更新为其状态,并且在到达时始终未定义, if(!(this.state.errorIntialValue || this.state.errorAge || errorRollno))并且返回 false。if 块中的代码永远不会被执行。我找不到合适的方法来实现这一点。我该怎么做?

2个回答

可以unstable_batchedUpdates按照此答案中的说明使用以使状态更新同步:

// this.state.foo === 0 here

ReactDOM.unstable_batchedUpdates(() => {
    this.setState({ foo: this.state.foo + 1});
});

// this.state.foo === 1 here

这个方法在这里不适用,需要说明有问题。

如果setState状态依赖于先前的状态,文档建议使用更新程序函数,如果评估的代码依赖于先前设置的状态,则使用回调函数:

setState() 并不总是立即更新组件。它可能会批量更新或推迟更新。这使得在调用 setState() 后立即读取 this.state 成为一个潜在的陷阱。相反,使用 componentDidUpdate 或 setState 回调 (setState(updater, callback)),这两者都保证在应用更新后触发。如果您需要根据之前的状态设置状态,请阅读下面的更新程序参数。

从代码中不清楚为什么临时值 ( errorIntialValue, errorAge, errorRollno) 应该存储在组件状态中。它们可能不应该并且应该只更新一次,例如:

if (errorIntialValue || errorAge || errorRollno) {
  // update the state with errors
} else {
  // update the state with data
}

正如@BoyWithSilverWings 指出的那样,最好使用 的功能版本setState以确保我们对稳定状态运行检查。否则,当您以this.onSave()编程方式调用时,您可能会对旧版本的状态进行操作。

考虑到这一点,我们使用回调进入第二个参数,因为@estus 给出了一个链接。

onSave=()=>{
    this.setState(currentState = > {
        errorIntialValue: currentState.intialValue<=0,
        errorAge: currentState.age>=25|| currentState.age<=-1,
        errorRollno: currentState.rollNo<0
    }, ({errorIntialValue, errorAge, errorRollno}) => {
       if([errorIntialValue, errorAge, errorRollno].some(isInvalid=> isInvalid)){    
          let newData={
               intialValue:this.state.intialValue,
               age:this.state.age,
               rollNo:this.state.rollNo
          }
          this.props.updateData(newData)
       } 
    });