如何同步更新状态

时间:2018-10-10 07:05:43

标签: reactjs axios setstate

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 个答案:

答案 0 :(得分:1)

可以按照this answer中的说明使用unstable_batchedUpdates来使状态更新同步:

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

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

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

此方法在这里不适用,需要它表明存在问题。

The documentation建议如果setState状态取决于先前的状态,则使用updater函数,而如果评估的代码取决于先前设置的状态,则使用回调函数:

  

setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState()之后立即读取this.state可能是一个陷阱。而是使用componentDidUpdate或setState回调(setState(updater,callback)),确保在应用更新后均能触发这两种方法。如果需要基于先前的状态来设置状态,请阅读以下有关updater参数的信息。

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

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

答案 1 :(得分:0)

正如@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)
       } 
    });