setState внутри цикла for не обновляет состояние: React + Typescript - PullRequest
0 голосов
/ 10 мая 2019

У меня есть массив объектов, который является объектом состояния, соответствующим учетной записи пользователя. Просто для целей проверки, если какое-либо из свойств объекта в массиве пусто, я устанавливаю для свойства проверки объекта состояния значение false. Поскольку я зацикливаюсь на использование цикла for, setState не устанавливает данные.

 this.state = {
      accounts: [{firstname:"",lastname:"",age:""}],
      validated: true
 };


onAdd = () => {

    let { accounts,validated } =  this.state;
    for(let i=0; i< accounts.length; i++){
      if(accounts[i].firstname === '' || accounts[i].age === '')
      {
        this.setState({validated: false},() => {}); // value is not getting set
        break;
      }
    }
    if(validated)
    {
      // some other operation 
      this.setState({validated: true},() => {});
    }
  }

render(){

   let { validated } =  this.state;
   return(
     {validated ? <span>Please fill in the details</span> : null}
       //based on the validated flag displaying the error message
   )
}

Ответы [ 3 ]

2 голосов
/ 10 мая 2019

Попробуйте выполнить отдельную проверку, которая проходит через массив в состоянии, и в зависимости от того, отсутствуют данные или нет, вы можете иметь временную переменную, равную true или false. Затем на основе временной переменной вы можете установить соответствующее состояние.

Дайте мне знать, если это работает:

onAdd = () => {

  let { accounts,validated } =  this.state;
  let tempValidate = true; //assume validate is true
  for(let i=0; i< accounts.length; i++){
    if(accounts[i].firstname === '' || accounts[i].age === '')
    {
      //this loop will check for the data validation, 
      //if it fails then you set the tempValidate to false and move on
       tempValidate = false
      break;
    }
  }

  // Set the state accordingly
  if(tempValidate)
  {
    this.setState({validated: true},() => {});
  } else {
    this.setState({validated: false},() => {});
  }
}
1 голос
/ 10 мая 2019

В вашем коде несколько проблем.Прежде всего this.setState является асинхронным, и поэтому вы не можете сказать, когда он действительно выполняется.

Так что, если вы вызываете

this.setState({validated: false},() => {});

, вы не можете полагать, что после этого this.state.validatedнемедленно false.

Поэтому после того, как вы позвоните this.setState, чтобы сделать validated == false, а затем проверьте:

if(this.state.validated)
{
  // some other operation 
  this.setState({validated: true},() => {});
}

Это может быть либо истинным, либо ложным.

Но в вашем коде вы извлекаете validated (что вы используете в условии if) в начале вашего метода.Это означает, что validated не изменится при изменении this.state.

Возможно, вы захотите использовать уже добавленный обратный вызов (() => {}), чтобы выполнить какое-то другое действие после изменения состояния или просто использовать обычныйДействительный вместо того, что связано с государством.

Как:

tmp = true;

for-loop {
  if(should not validate) {
    tmp = false;
    this.setState({validated: false});
    break;
  }

if(tmp) {
  this.setState({validated: true},() => {});
}
1 голос
/ 10 мая 2019

setState - это функция async.Так что это не будет работать в циклах.

Из документов

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

Также см. это .

...