简体   繁体   English

循环内的setState不会更新状态:React + Typescript

[英]setState inside for loop does not update the state: React+Typescript

I am having an array of objects which is a state object that corresponds to a user account. 我有一个对象数组,这是一个与用户帐户相对应的状态对象。 Just for a validation purpose if any one of the object property within array is empty, I am setting a validation property of state object to false. 仅出于验证目的,如果数组内的任何对象属性为空,则将状态对象的验证属性设置为false。 Since I am looping using for loop, the setState is not setting data. 由于我正在循环使用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
   )
}

Try to have a separate check that goes through the array in the state and depending if the data is missing or not you can have the temporary variable be either true or false. 尝试通过状态单独检查数组,并根据数据是否丢失来确定临时变量为true还是false。 Then based on the temp variable you can set the state accordingly. 然后,根据temp变量,您可以相应地设置状态。

Let me know if this works: 让我知道这个是否奏效:

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},() => {});
  }
}

setState is async function. setStateasync函数。 So it won't work in loops. 因此它不会循环工作。

From the docs 来自文档

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.

Also refer this . 另请参阅

There are multiple issues in your code. 您的代码中存在多个问题。 First of all this.setState is asynchronous and therefore you can not say when it really is executed. 首先, this.setState是异步的,因此您不能说它何时真正执行。

So if you call 所以如果你打电话

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

you can not rely that after that this.state.validated is false immediatly. this.state.validated立即为false之后,您不能再依靠它了。

So after you call this.setState to make validated == false and then check: 因此,在调用this.setState使其validated == false之后,请检查:

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

It might be either true or false. 可能为true或false。

But in your code you're extracting validated (what you're using in the if-condition) at the beginning of your method. 但是在您的代码中,您将在方法开始时提取validated (在if条件中使用的内容)。 That means validated won't change when this.state changes. 这意味着,当this.state更改时, validated不会更改。

You might want to use the callback you already added ( () => {} ) to perform some other action after the state changed or just use a normal valiable instead of something related to the state. 您可能想使用已经添加的回调( () => {} )在状态更改后执行其他一些操作,或者只使用常规变量而不是与状态相关的东西。

Like: 喜欢:

tmp = true;

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

if(tmp) {
  this.setState({validated: true},() => {});
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM