The issue: When I use this.setState and I output the state in the callback, it doesn't change at all but when I nest the setstate inside a setstate it will then work correctly.
Example: This doesn't work -
this.setState({
data: newData
});
This does work -
this.setState({
data: newData
}, () => {
this.setState({
data: newData
});
});
Does this have something to do with the way react batches state updates?
This is the actual code in which the setstate doesn't work unless I nest it (I've tried commenting everything out in this function and using setState to set coursePage to null but it doesn't work unless it's nested):
cancelCPIndexChange(index){
let temp = this.state.coursePages;
this.hideEditingCoursePage(index);
let canceledIndex = temp[index];
temp = temp.slice(0, index).concat(temp.slice(index+1));
temp = temp.slice(0, parseInt(canceledIndex.course_pageindex)-1).concat(canceledIndex).concat(temp.slice(parseInt(canceledIndex.course_pageindex)-1));
this.setState({
coursePages: temp
}, () => {this.setState({
coursePages: temp
});
});
}
This is another function on the same level as cancelCPIndexChanges that is able to modify the state of coursePages:
showEditingCoursePage(index){
let temp = this.state.coursePages;
temp[index].editingCoursePage = true;
this.setState({
coursePages: temp
});
}
These functions are in course.js. Both these functions are passed down to CoursePages.js and then to CoursePage.js.
According to: https://facebook.github.io/react/docs/component-api.html
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.
(I've noticed this myself in the past)
I'm not 100% certain, but I'd guess that the second
setState
in your callback function is "flushing" the pending state transition before creating the second one.I'm not clear on where you want to consume the new value of state? It ought to be in the
render
method where you can be sure it's been updated (As the state transition triggers the render). If you want to use it immediately after thesetState
you still have the reference to the value, so can use that directly.As said setState behaves asynchronously. There are two ways you can access the newly updated state value before render
Using a call back function for setState method
Use componentDidUpdate method. Using nextState param you can access the latest state. But make sure you should use setState method inside that