问题
I know this question has been asked more times in different flavours, but I didn’t find the "right" answer yet (maybe there just isn't one), so I’m looking for the "most Flux" one.
Simple example:
- two components -
LoginForm
andInformation
- user has to provide his/hers login information, submit the form and only after that he/she has right to "ask" for the information (this should be done automatically after login)
Project structure along these lines:
+ actions |-- LoginAction |-- InfoAction + api |-- API + components |-- LoginForm |-- Information + stores |-- LoginStore |-- InfoStore
Options:
1.
LoginForm._onSubmit()
callsLoginAction.login()
LoginAction.login()
callsAPI.login()
with callbacks/promises and then in case of successful login it callsInfoAction.requestInfo()
2.
LoginForm._onSubmit()
callsAPI.login()
- if
API.login()
is succesful it callsLoginAction.loginSuccess()
and:- either
InfoAction.requestInfo()
which callsAPI.requestInfo()
- or
API.requestInfo()
which then callsInfoAction.infoSuccess()
- either
3.
LoginForm._onSubmit()
callsLoginAction.login()
InfoStore
listens toLOGIN_OK
action and it calls theAPI.requestInfo()
API.requestInfo()
callsInfoAction.infoSuccess()
and that dispatchesINFO_OK
event with payload of the specific info that is going to be stored inInfoStore
(4.)
calling API/ServiceProvider or ActionCreators from componentWillMount
or componentDidMount
seems inherently bad. Not really a (good) option, but I’m putting it here for the sake of completeness.
My evaluation:
1. Good in the "old style" of callback/promise based JS, but doesn’t seem to be the Flux way, because we should avoid chaning actions. Just fire-and-forget.
2. Breaks the "Flux diagram" slightly - components speak to API or ServiceProviders and not to ActionCreators directly. I'm not sure about whether this is good or bad. It seems to be "one-way" (good) and avoids circular requires (good). I personally prefer this option (specifically the 2.2. one)
3. I personaly avoid this approach because it would mean Store talking to the API/ServiceProvider which breaks the “Flux diagram”, but again, I don’t know if it’s really bad (maybe it’s just me not being used to the Flux way of doing things). Even @fisherwebdev seems to be ok with this (e.g. https://stackoverflow.com/a/26637579/5053194), but is it really the best approach?
4. Bad, bad, bad!
Question
Which one is "the best" and/or is there any other "most Flux" option to do this?
回答1:
I recently watched an informative panel discussion that had, among others, two Facebook developers working on large-scale projects that used React/Flux. What struck me was that they took completely different approaches to the same problem -- and both seem perfectly good.
That said, here's how I'd handle it.
LoginForm.onSubmit
callsLoginAction.login
.LoginAction
callsAPI.login
and, upon success, the Dispatcher launches an actionType of something likeConstants.LOGGED_IN
with data of theuser_id
- A
UserStore
, listening forConstants.LOGGED_IN
makes a call toAPI.userInfo
, passing theuser_id
that was in the dispatch. (Having a store get information directly from the API was one of the things one of the FB guys said they do routinely, reserving actions for updates and things of that nature.) UserStore
saves info into itscurrent_user
and emits aCHANGE
- Affected components request an update to
UserStore
Now, if you want to get trickier, you can have the store add arguments to its emit
method, so that the affected components could pick up (a)the nature of what changed and (b)the actual data.
Hopefully, that's food for thought!
来源:https://stackoverflow.com/questions/31076834/dispatching-cascading-dependent-async-requests-in-flux-react