问题
tl;dr: Within a Redux middleware function, is it okay to dispatch a new action after calling next to finish updating the store?
I'm building a HackerNews reader using Flutter and built-flutter-redux, based off of Brian Egan's TodoMVC example. It uses HN's Firebase-backed API to pull data:
https://github.com/HackerNews/API
My actions look like this right now:
ActionDispatcher<Null> fetchHackerNewsTopStories;
ActionDispatcher<List<int>> fetchHackerNewsTopStoriesSuccess;
ActionDispatcher<Null> fetchHackerNewsTopStoriesFailure;
ActionDispatcher<Null> fetchNextHackerNewsItem;
ActionDispatcher<HackerNewsItem> fetchHackerNewsItemSuccess;
ActionDispatcher<Null> fetchHackerNewsItemFailure;
There's a piece of middleware that listens for the fetchHackerNewsTopStories action and kicks off a call to the API:
MiddlewareHandler<AppState, AppStateBuilder, AppActions, Null>
createFetchHackerNewsTopStories(HackerNewsRepository service) {
return (MiddlewareApi<AppState, AppStateBuilder, AppActions> api,
ActionHandler next, Action<Null> action) {
service.fetchHackerNewsTopStories().then((ids) {
return api.actions.fetchHackerNewsTopStoriesSuccess(ids);
}).catchError(api.actions.fetchHackerNewsTopStoriesFailure);
next(action);
};
}
When it returns, I update my app's state with the list of IDs.
At some point I need to dispatch another action, fetchNextHackerNewsItem. There's another middleware function that will listen for that action and request the details for the the first story. When those details arrive, it'll request the next story, and so on until everything's updated.
What I'd like to know is whether I can do this:
// Invoked when REST call for the list of top story IDs completes.
MiddlewareHandler<AppState, AppStateBuilder, AppActions, List<int>>
createFetchHackerNewsTopStoriesSuccess() {
return (MiddlewareApi<AppState, AppStateBuilder, AppActions> api,
ActionHandler next, Action<List<int>> action) {
next(action);
api.actions.fetchNextHackerNewsItem(); // Is this cool?
};
}
// Initiates a request for a single story's details.
MiddlewareHandler<AppState, AppStateBuilder, AppActions, Null>
createFetchNextHackerNewsItem(HackerNewsRepository service) {
return (MiddlewareApi<AppState, AppStateBuilder, AppActions> api,
ActionHandler next, Action<Null> action) {
int nextId = api.state.topStoryIds[api.state.loadedUpToIndex];
service.fetchHackerNewsItem(nextId).then((item) {
return api.actions.fetchHackerNewsItemSuccess(item);
}).catchError(api.actions.fetchHackerNewsTopStoriesFailure);
next(action);
};
}
Because createFetchNextHackerNewsItem relies on the app's state (api.state.topStoryIds[api.state.loadedUpToIndex]), I'd like for it to run after the store is updated by the next(action) call.
Is it cool to dispatch new actions in Redux middleware after calling next, or is that some kind of anti-pattern? If it is an anti-pattern, what's the best way to implement this flow?
回答1:
Yes, it's fine - a middleware can do literally anything it wants when an action is dispatched. That includes modifying / logging / delaying/ swapping / ignoring the original action, as well as dispatching additional actions.
来源:https://stackoverflow.com/questions/50353571/should-next-always-be-invoked-last-in-redux-middleware