8

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

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

如何用 [] 替换包含 [1,2] 的数组,然后用 [3] 替换包含以下内容的数组:

  1. this.state.warnErrorTypes 是一个以 [] 开头的数组
  2. 根据条件,将 2 推入 Array
  3. 根据条件,将 1 推入 Array。
  4. 根据条件,不会将 3 推入 Array
  5. 暂停。用户与 UI 交互
  6. 数组空白:this.setState({warnErrorTypes:[]})
  7. 根据条件,不会将 2 推入 Array
  8. 根据条件,不会将 1 推入 Array
  9. 根据条件,将 3 推入 Array。

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

4

3 回答 3

13

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()如果您不等待它们首先绑定,那么在此之前的连续调用将“覆盖”同名键值更新。

于 2015-05-01T20:18:22.190 回答
0

选项 3,如 Anders Ekdahl 所述:

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

    // ...

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

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

我们提供的合并操作setState总是异步应用,在未来的某个时候,由 React 自行决定。当setState()函数返回时,我们的操作还没有被应用,它只是被排队了。

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

于 2018-02-05T02:34:59.547 回答
-2

您也可以使用它来清除数组:

   this.state.your_array.length = 0;
   setState({your_array});
于 2019-06-06T00:09:17.570 回答