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 menting 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.
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 menting 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.
Share Improve this question edited Dec 25, 2015 at 9:18 Kirill Fuchs 13.7k4 gold badges43 silver badges73 bronze badges asked Dec 23, 2015 at 19:56 RecurRecur 1,4282 gold badges17 silver badges30 bronze badges 6-
2
No,
this.setState
always works. Can you reproduce your issue in a fiddle? – Henrik Andersson Commented Dec 23, 2015 at 19:59 - How do you call set state? It might be a "this" scope issue. – Marcin Zablocki Commented Dec 23, 2015 at 21:04
- I doubt I can replicate the issue in fiddle. The other functions on the same scope level that use setState work just fine except for this particular function. I've binded the function at the correct level too. – Recur Commented Dec 23, 2015 at 21:37
-
Unless you are confident that something besides
setState
is causing the issue, I don't see how you can be confident you wont be able to reproduce it in a fiddle. And if thats the case, we wont be able to help you without seeing the code you think is causing the issue. – Kyeotic Commented Dec 23, 2015 at 21:43 - I've updated my post with more information... hopefully there's more clues for you guys. – Recur Commented Dec 23, 2015 at 22:34
2 Answers
Reset to default 2According to: https://facebook.github.io/react/docs/ponent-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 the setState
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 ponentDidUpdate method. Using nextState param you can access the latest state. But make sure you should use setState method inside that