I feel like the core of this issue isn’t really specific to React. You’ll see this in any declarative UI library. In other words, in any library where you decorate a model and the library handles the imperative conversion to DOM within a lifecycle.
I can remember learning Angular.js (coming from ultra imperative jQuery land) and running into essentially the same source of confusion. Sometimes, you would make changes to your $scope (which we can compare to this.state in React) but you wouldn’t see them propagate, because a $digest (which we can compare to React’s render cycle or “reconciliation”) hadn’t occurred yet. There are countless StackOverflow questions where the solution is simply to call $scope.$digest() (comparable to this.forceUpdate() or simply waiting for a complete render cycle triggered by setState to complete).
Ultimately, I think the power that setState provides is worth the initial confusion. We wouldn’t want to have to worry about calling setState multiple times with a single render cycle, leading to multiple (and possibly infinite) subsequent render cycles. It would make it easier to write poorly performing applications.
A small example is a component that calls setState in an event handler and also calls another function which conditionally needs to call `setState`…
<div onClick={ () => { // this.state.toggled = false right now this.setState({ toggled: true }) if (toggled) {
doSomethingElse()
}
}} />...doSomethingElse() {
this.setState({ thatThingWeDoWhenToggled: true ])
}
It would be very wasteful for each of these to trigger a full render. Of course this is a simplified example that could be combined into one setState call but there are times you need this functionality and you can’t combine them. At least not without making a mess of your code. Especially when you start typing multiple components together.
A n00b might do this instead…
this.setState({ toggled: true })if (this.state.toggled) { // still false
doSomethingElse()
}
Ultimately, you have just been bitten by The Law of Leaky Abstractions.
