Как обновить состояние в реагировать синхронно - PullRequest
0 голосов
/ 10 октября 2018
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 голосов
/ 10 октября 2018

Можно использовать unstable_batchedUpdates, как описано в в этом ответе , чтобы синхронизировать обновления состояния:

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

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

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

Этот метод здесь не применим, необходимость в нем указывает на то, чтоэто проблема.

В документации предлагается использовать функцию обновления, если состояние setState зависит от предыдущего состояния, и использовать функцию обратного вызова, если вычисленный код зависит от ранее установленного состояния:

setState () не всегда сразу обновляет компонент.Это может пакетировать или отложить обновление до позже.Это делает чтение this.state сразу после вызова setState () потенциальной ловушкой.Вместо этого используйте componentDidUpdate или обратный вызов setState (setState (Updater, callback)), который гарантированно сработает после применения обновления.Если вам нужно установить состояние на основе предыдущего состояния, прочитайте об аргументе средства обновления ниже.

Из кода неясно, почему временные значения (errorIntialValue, errorAge, errorRollno)должен храниться в состоянии компонента.Они, вероятно, не должны и должны обновляться только один раз, что-то вроде:

if (errorIntialValue || errorAge || errorRollno) {
  // update the state with errors
} else {
  // update the state with data
}
0 голосов
/ 10 октября 2018

Как отметил @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)
       } 
    });
...