Closed bradencanderson closed 5 years ago
Thanks for the report! Your description was very clear!
@bradencanderson It's not possible for an AJAX request to return between getInitialState and componentDidMount because those two methods are called synchronously in the same tick, so you must be seeing something else. Can you clarify?
Yep, the issue is with synchronous state mutations. What I'm doing here is setting a flag in a Store to keep track of whether an AJAX request is ongoing. So when a component gets its initial state using StateFromStore it requests state from a DataStore, which in turn sends a message 'request_data'
over the flux dispatcher. Two Stores read this message -- (1) DataStore (which dispatches the AJAX request asynchronously), and (2) ViewStore (which updates its _isLoading
flag synchronously). Some view components depend on ViewStore, and should re-render when ViewStore._isLoading is set to true.
The issue is that I'm doing some synchronous state mutations between getInitialState()
and when a component actually gets mounted.
Hopefully that clarifies.
@zgotsch's PR fixes my issue.
The problem seems to be that getInitialState brings state into a component, but addChangeListeners is not called until the component is mounted. This can lead to inconsistent state.
For example:
Store._isLoading = false
this.state.isLoading = false
using StateFromStoreMixinStore._isLoading = true
. Store has no change listenersStore._isLoading = false
. Listeners are notifiedWhat I'd like is for the view component to be added as a change listener to Store at the same time its initial state is loaded, so that we don't miss changes in step 3.
Adding
this.setState(this.getInitialState());
tocomponentDidMount
fixed this.