I seem to have encountered a situation where I cannot avoid the dispatch-within-a-dispatch problem in Flux.
I've read a few similar questions regarding this problem but none of them seem to have a good solution besides setTimeout
hacks, which I would like to avoid.
I'm actually using alt.js instead of Flux but I think the concepts are the same.
Scenario
Imagine a component that initially renders a login form. When a user logs in, this triggers an XHR that eventually responds with authentication information (eg. the user name), and then fetches some secure data based on the authentication information and renders it instead of the login form.
The problem I have is when I attempt to fire an action to fetch data based on the XHR response, it is still in the dispatch of the LOGIN_RESPONSE
action, and triggers the dreaded
Error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
Example
I have created this jsfiddle to demonstrate the problem.
I have a Wrapper
component which either renders a login button or a Contents
child component, based on whether the user is set in MyStore
.
- First, the login button is rendered in
Wrapper
component. - Clicking the button dispatches the
LOGIN
action. - After a delay, the
LOGIN_RESPONSE
action is dispatched (via the async mechanism in alt.js). - This action triggers
MyStore
to update the user name. Wrapper
component observes the store change and updates its state.- This causes
Wrapper
to renderContent
component instead of the login button. Content
component, on mount, attempts to dispatch theFETCH_DATA
action, which fails because the dispatcher is still dispatchingLOGIN_RESPONSE
. (If I wrap theFETCH_DATA
dispatch in asetTimeout
it works, but it feels like a hack).
Variations of this seems to be a common scenario. In fact almost all the related questions have a similar scenario, but with no good or concrete answers.
- React - Authentication process : Cannot dispatch in the middle of a dispatch
- Dispatching cascading/dependent async requests in Flux/React
- Flux Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch
Is there something intrinsically wrong with this data flow? What is the proper Flux way of doing something like this?