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
If _buildState causes a store to trigger, that might call back into the component's _buildState before the first one has finished/returned. That can really mess up state updates since the setState will arrive in the wrong order*. Also, both _buildState will probably see the same this.state as the "previous state" since setState is not guaranteed to update this.state synchronously. Note: This is only a problem if _buildState depends on the previous state, or causes a change in the outside world (discouraged). Otherwise, both _buildState should return the same thing.
Is the solution to just use setState(updater) in #69? Or do we need to track this problem explicitly at runtime? Our current solution is to forbid store triggering from getters. That is manually enforced and can be error-prone. We could add runtime checks for that.
The MyComponent._buildStateWithAutoSubscriptions (second) will finish and call setState, and then the stack will unwind to allow the MyComponent._buildStateWithAutoSubscriptions (first) to finish and call setState.
The text was updated successfully, but these errors were encountered:
Interesting - we prevent re-entry on store triggers, we should probably do that for components too.
Either that or prevent trigger from any _buildState path
private _resolveThrottledCallbacks = () => {
// Prevent a store from trigginer while it's already in a trigger state
if (this._isTriggering) {
this._triggerPending = true;
return;
}
@berickson1 Indeed, StoreBase will finish all callbacks before calling them again. I was thinking of an explicit solution (e.g. in ComponentBase) so the code has this problem mentioned, but this implicit solution should work. So long as we are confident this problem will not regress.
If
_buildState
causes a store to trigger, that might call back into the component's_buildState
before the first one has finished/returned. That can really mess up state updates since thesetState
will arrive in the wrong order*
. Also, both_buildState
will probably see the samethis.state
as the "previous state" sincesetState
is not guaranteed to updatethis.state
synchronously. Note: This is only a problem if_buildState
depends on the previous state, or causes a change in the outside world (discouraged). Otherwise, both_buildState
should return the same thing.Is the solution to just use
setState(updater)
in #69? Or do we need to track this problem explicitly at runtime? Our current solution is to forbid store triggering from getters. That is manually enforced and can be error-prone. We could add runtime checks for that.*
Call stack:
FooStore.trigger
->MyComponent._buildStateWithAutoSubscriptions (first)
->MyComponent._buildState
->FooStore.getFoo
->FooStore.trigger
->MyComponent._buildStateWithAutoSubscriptions (second)
->MyComponent._buildState
The
MyComponent._buildStateWithAutoSubscriptions (second)
will finish and callsetState
, and then the stack will unwind to allow theMyComponent._buildStateWithAutoSubscriptions (first)
to finish and callsetState
.The text was updated successfully, but these errors were encountered: