Tengo una matriz de objetos que es un objeto de estado que corresponde a una cuenta de usuario. Solo para fines de validación si cualquiera de las propiedades del objeto dentro de la matriz está vacía, estoy configurando una propiedad de validación del objeto de estado en falso. Como estoy haciendo un ciclo usando for loop, setState no está configurando datos.

 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
   )
}
0
vjr12 10 may. 2019 a las 12:19

3 respuestas

La mejor respuesta

Hay múltiples problemas en su código. En primer lugar, this.setState es asíncrono y, por lo tanto, no se puede decir cuándo se ejecuta realmente.

Entonces si llamas

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

No puede confiar en que después de eso {{X 0}} sea falso de inmediato.

Entonces, después de llamar a this.setState para hacer validated == false y luego verificar:

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

Podría ser verdadera o falsa.

Pero en su código está extrayendo validated (lo que está usando en la condición if) al comienzo de su método. Eso significa que validated no cambiará cuando this.state cambie.

Es posible que desee utilizar la devolución de llamada que ya agregó (() => {}) para realizar alguna otra acción después de que el estado cambió o simplemente usar un valor normal en lugar de algo relacionado con el estado.

Como:

tmp = true;

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

if(tmp) {
  this.setState({validated: true},() => {});
}
1
BreakBB 10 may. 2019 a las 09:34

Intente tener una verificación por separado que atraviese la matriz en el estado y, dependiendo de si faltan datos o no, puede hacer que la variable temporal sea verdadera o falsa. Luego, según la variable temporal, puede establecer el estado en consecuencia.

Hazme saber si esto funciona:

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},() => {});
  }
}
2
Constantin Chirila 10 may. 2019 a las 09:31

setState es la función async. Por lo tanto, no funcionará en bucles.

Del documentos

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.

Consulte también this.

1
ravibagul91 10 may. 2019 a las 09:31