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

試著忘記壹切 提交于 2019-12-05 10:51:38

setState is atomic, so you can't just issue multiple setState() calls and expect things to work, you either have to wait for the state to update before updating it again, or shadow an instance variable.

Option 1:

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

This is fairly cumbersome. The other option is to use a "real" instance variable that you send over as state at moments when you need to.

Option 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 });
}

Remember that updating the state means you have changed an aspect of your component that demands a rerender, so don't use setState if you don't intend the component to rerender, like between clearing the array and refilling it. Do that stuff separately, and only update the state once you're done.

Option 3:

You could also do this by taking out the state values, running your updates, and then rebinding, without ever building a persistant instance variable:

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 });
}

The net effect is the same: you only update your UI when your data is in some stable configuration, so if you think you're calling setState() more than once between renders, that's a problem: every setState() call may trigger a render, and consecutive setState() may "override" each other if you don't wait for them to bind first.

Option 3, as mentioned by Anders Ekdahl:

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

    // ...

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

This pattern is useful if you need to refer to the previous existing state when you perform your state update. I'm not sure if you really need the previous state in your example, but I will explain this pattern as if you did.

The merge operation we provide to setState is always applied asynchronously, at some point in the future, at React's discretion. When the setState() function returns, our operation has not been applied, it has only been queued.

Therefore we should never use this.state in our state updater, because that might be out of date: an old copy of the state. If we need to know the previous state, we should receive the state argument in the function we pass to setState, and use that.

You can as well use this to clear array without using setState:

   this.state.your_array.length = 0;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!