You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The issue in question is caused by our mutable _renderCallbacks and the timing of which we push our new state-setting callback into it.
In the test-scenario we have a component that mounts without children due to a loading state variable being true, imagine a spinner or something instead here.
After our component mounts we set this variable to false effectively mounting our child-component which has a componentDidMount of itself which calls a setState on the parent, due to this setState we will synchronously push our setState callback onto the _renderCallbacks which is the one from the render we are still processing.
Now why do we call it with componentDidUpdate and not without? Well we push a _renderCallback when we are updating from loading true to false which puts this parent component into the renderQueue which we consume in the inverse order of the tree (child --> parent) this leads us to calling the setState callback when the intermediary render completes (read not the one where we update the parent state).
To solve this we ensure that we only push this callback when we are consuming the render coupled to this dirty state by means of adding a _stateCallbacks mechanism that is consumed when the component is handled.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3742
The issue in question is caused by our mutable _renderCallbacks and the timing of which we push our new state-setting callback into it.
In the test-scenario we have a component that mounts without children due to a
loading
state variable being true, imagine a spinner or something instead here.After our component mounts we set this variable to
false
effectively mounting our child-component which has acomponentDidMount
of itself which calls a setState on the parent, due to thissetState
we will synchronously push oursetState
callback onto the_renderCallbacks
which is the one from the render we are still processing.Now why do we call it with
componentDidUpdate
and not without? Well we push a_renderCallback
when we are updating from loading true to false which puts this parent component into the renderQueue which we consume in the inverse order of the tree (child --> parent) this leads us to calling the setState callback when the intermediary render completes (read not the one where we update the parent state).To solve this we ensure that we only push this callback when we are consuming the render coupled to this dirty state by means of adding a
_stateCallbacks
mechanism that is consumed when the component is handled.