如何在 React 中使用 setState() 来 blank/clear 数组的值

How to use setState() in React to blank/clear the value of an array

我正在尝试清除数组,但遇到了问题。 this.setState({warnErrorTypes:[]})

我不确定我是否正在处理竞争条件,或者具体问题是什么,但我可以看到我的数组的值在我需要将其值重置为的情况下一直是错误的[].

如果满足以下条件,如何将包含 [1,2] 的数组替换为 [],然后再替换为 [3]:

  1. this.state.warnErrorTypes 是一个以 []
  2. 开头的数组
  3. 根据条件,将 2 压入数组
  4. 根据条件,将 1 压入数组。
  5. 根据条件,3 未被压入数组
  6. 暂停。用户与 UI
  7. 互动
  8. 数组为空白:this.setState({warnErrorTypes:[]})
  9. 根据条件,2 未被压入数组
  10. 根据条件,未将 1 压入数组
  11. 根据条件,将 3 压入数组。

上述逻辑的结果总是[2,1,3],而我期望它是[3]

setState 被聚合和安排,它不是 运行 原子和即时的,所以你不能只发出多个 setState() 调用并期望事情起作用,你要么必须等待让状态在再次更新之前更新,或者使用实例变量。

选项 1:

moo: function() {
  this.setState({
    myarr: []
  }, function() { // called by React after the state is updated
    this.setState({
      myarr: [3]
    });
  });
}

这相当麻烦并且取决于您在做什么,主要是错误的代码。另一种选择是使用您在需要时作为状态发送的“真实”实例变量。

选项 2:

getInitialState: function() {
  this.mylist = [];
  return {
    myarr: this.mylist
  };
},
...
moo: function() {
  this.mylist = [];
  for(var i=0; i<10; i++) {
    this.mylist.push(i);
  }
  this.setState({ myarr: this.mylist });
}

请记住,更新状态意味着您更改了组件的某个方面,需要重新呈现,因此如果您不打算重新呈现组件,请不要使用 setState,例如在清除数组和重新填充数组之间。分别做这些事情,并且只在完成后更新状态。

选项 3:

您也可以通过取出状态值,运行更新您的更新,然后重新绑定来完成此操作,而无需构建持久性实例变量:

moo: function() {
  var list = this.state.myarr;
  while(list.length > 0) { list.splice(0,1); }
  for(var i=0; i<10; i++) { list.push(i); }
  this.setState({ myarr: list });
}

净效果是一样的:当你的数据处于某种稳定的配置时,你 更新你的 UI,所以如果你认为你正在调用 setState() 在渲染之间不止一次,这是一个问题:每个 setState() 调用都可能“最终”触发渲染,并且在此之前连续的 setState() 调用将“覆盖”同名键值更新如果你不等他们先绑定。

选项 3,如 Anders Ekdahl 所述:

  moo () {
    this.setState(state => ({
      myarr: []
    }));

    // ...

    if (weShouldAddAThree) {
      this.setState(state => ({
        myarr: [ ...state.myarr, 3 ]   // like push but without mutation
      }));
    }
  }

如果您在执行状态更新时需要参考以前存在的状态,则此模式很有用。我不确定您是否真的需要示例中的先前状态,但我会像您一样解释这种模式。

我们提供给 setState 的合并操作始终是异步应用的,在将来的某个时刻,setState()函数returns的时候,我们的操作还没有应用,只是排队了。

因此我们不应该在我们的状态更新器中使用 this.state,因为那可能已经过时了:状态的旧副本。如果我们需要知道之前的状态,我们应该在传递给 setState 的函数中接收 state 参数,并使用它。

你也可以用它来清除数组:

   this.state.your_array.length = 0;
   setState({your_array});