问题
I have a scenario where I feel like I need to dispatch an action in response to another action, and I don't know the best way to sort it out.
An action is dispatched in response to an HTTP response, something like:
type: 'auth'
data: { username: 'tom' }
Because that response was successful, I want to dispatch an action to send the user to the homepage:
type: 'navigate'
date: { where: 'home' }
This seems like a sensible flow to me: this thing happened, so now I want this thing to happen. Trouble is, the Flux Dispatcher doesn't allow this as we are still in the dispatch cycle. I get why dispatching while dispatching is a bad idea.
Some people have solved this with multiple dispatchers, whilst it seems that the Flux authors are sure that you only need one and that you need to rethink your stores.
I don't see how I could restructure my stores to facilitate this without obfuscating the intent. My UserStore
knows about auth
actions, and my RouteStore
knows about navigate
actions. Any suggestions on how the stores could be changed to facilitate this would be appreciated.
I feel like a setImmediate
would work, but it seems a bit dirty. I also think a dispatcher that queued actions might help but I can feel in my bones that this could cause nasty problems.
What is the best way out of this?
回答1:
Usually, the solution to this problem is to to back up and look at the original action, and to waitFor the value that you are trying to send in the second action, if a derived value is required.
So in this case you would respond only to 'auth' in both the UserStore and the RouteStore.
回答2:
You should look back how you are trying to create this flow.
You say that you need to create an action in response to another action, right? So, let's name this the "ActionForwarderStore".
We end up with a flow like this:
AuthAction --> Dispatcher --+--> UserStore
|
+--> ActionForwarderStore --+
|
+--------------------------------------------+
|
+-> Dispatcher -----> RouteStore
You see that you still have someone that understands that a AuthAction
should end up changing a route? This is the ActionForwarderStore
. As Flux suggests that every Store listens to every Action, this knowledge of the AuthAction
ending up in a route change can go straight into RouteStore
. Like this:
AuthAction --> Dispatcher --+--> UserStore
|
+--> RouteStore
Remember that Flux was "created" in order to avoid the unpredictability of MVC. If you keep all your route changes into RouteStore
, you just need to look at this Store code to understand what Actions will cause a route change. If you go in the way of creating an action in response to another action, you will only know that NavigateAction
changes routes, and you will need to look at the other Stores to check which ones are triggering this Action in response to others.
This is what Flux names as "unidirectional flow". It's easy to catch problems this way because this is the only flow allowed. If you click a button and it changes the route, you can know for sure that the action that the click dispatched is causing the route change, there are no cascading actions.
来源:https://stackoverflow.com/questions/26934953/dispatching-further-actions-when-handling-actions