Wednesday, June 5, 2024
 Popular · Latest · Hot · Upcoming
57
rated 0 times [  60] [ 3]  / answers: 1 / hits: 37200  / 9 Years ago, fri, may 1, 2015, 12:00:00

I am trying to clear an array, but I'm having trouble.
this.setState({warnErrorTypes:[]})



I'm not sure if I am dealing with a race condition, or what the specific issue is, but I can see that the value of my array is consistently wrong in the case that I need to reset its value to [].



How does one replace an array that contains [1,2] with [] then subsequently [3] where the following are true:




  1. this.state.warnErrorTypes is an Array which starts out with []

  2. Based on condition, 2 is pushed in Array

  3. Based on condition, 1 is pushed in Array.

  4. Based on condition, 3 is NOT pushed in Array

  5. Pause. User interacts with UI

  6. Array is blanked: this.setState({warnErrorTypes:[]})

  7. Based on condition, 2 is NOT pushed in Array

  8. Based on condition, 1 is NOT pushed in Array

  9. Based on condition, 3 is pushed in Array.



The result of the logic above is always [2,1,3], when I expect it to be [3].


More From » reactjs

 Answers
3

setState gets aggregated and scheduled, it does not run atomic and immediate, 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 use an instance variable.


Option 1:


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

This is fairly cumbersome and depending on what you're doing, mostly just bad code. 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() {
this.mylist = [];
return {
myarr: this.mylist
};
},

...

doSomething() {
this.mylist = [];
for(let 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 in a way that requires a rerender, so don't use setState for "intermediate" changes, i.e. changes where a render is not necessary, like clearing the array before refilling it (the state change is the new data, not the intermediate cleared state). 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 persistent instance variable:


doSomething {
const list = this.state.myarr;
list.splice(0, list.length);
for (let 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're calling setState() more than once between renders for the same state key, that's a problem: every setState() call may trigger a render "eventually", and consecutive setState() calls before that happens will override same-named-key updates if you don't wait for them to be processed first.


[#66789] Wednesday, April 29, 2015, 9 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
osvaldo

Total Points: 102
Total Questions: 95
Total Answers: 102

Location: Fiji
Member since Wed, Jul 14, 2021
3 Years ago
osvaldo questions
Thu, Jan 28, 21, 00:00, 3 Years ago
Sun, Sep 20, 20, 00:00, 4 Years ago
Fri, Apr 24, 20, 00:00, 4 Years ago
;