redux-saga: Saga cannot catch actions dispatched by store enhancers
I need to use store enhancer (reactReduxFirebase from react-redux-firebase) in my redux app. This enhancer dispatches an action, it looks more or less like this (much simplified):
const reactReduxFirebase = (next) => {
return (reducer, initialState, middleware) => {
const store = next(reducer, initialState, middleware);
store.dispatch({
type: 'DUMMY_ACTION'
});
return store;
}
}
// usage
const sagaMiddleware = createSagaMiddleware();
const middleware = [sagaMiddleware];
const store = createStore(
reducer,
initialState,
compose(
applyMiddleware(...middleware),
reactReduxFirebase
)
);
sagaMiddleware.run(sagas);
// sagas.js
function* handle(action) {
console.log(action);
}
function* saga() {
yield takeEvery('*', handle);
}
export default saga;
I want saga to listen to all actions and console.log them, but it doesn’t catch ‘DUMMY_ACTION’ dispatched by enhancer, because it’s being dispatched before saga starts to listen (sagaMiddleware.run(sagas);
). From redux-saga docs it seems that saga must be run after applyMiddleware, so I cannot make saga run before enhancer. Is there any way to make it work, so the saga will catch an action from enhancer as well?
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 12
- Comments: 16 (7 by maintainers)
I’m interested in experimenting with a
redux-saga
enhancer but the benefits need to be more clear. This would involve new code and with that testing, debugging, and docs; a non-trivial amount of work. Also, we wouldn’t replace our current middleware system for it, this would have to be additive.Furthermore, after reading the
electron-redux
enchancer, I’m confused why they decided to make it an enhancer. I could be missing something, but the way it works is the enhancer appears to be listening for IPC events and dispatching actions. They also monkey-patchdispatch
to forward actions to other redux stores via IPC. If that’s right then this library could be implemented as middleware.There could be other reasons why it’s an enhancer and not middleware, but it doesn’t seem obvious to me with a cursory read of their code.
I’ve also implemented something similar myself a few years ago in electron. It wasn’t that hard to manage on our own without this library. Not ideal, but food for thought nonetheless.
It’s not that - we can’t even know the origin of actions. The point here was that there are some init-time actions dispatched from enhancers and those are simply dispatched before saga gets “installed”. It’s a timing~ issue.
I don’t have such plans - simply because I don’t have time to fully evaluate this etc. Perhaps @neurosnap would be more interested in this (or maybe not).
I understand that this is probably very annoying when it happens - but OTOH this doesn’t really happen a lot. Although, when it does, it’s hard to tell on the spot what happens. That’s why I’m not saying that such a change would be impossible - it’s just that it’s a delicate one. For example, at the moment, we recommend using Saga as your last middleware but this implies that it should be the very first thing installed in the chain (otherwise you always have a chance of missing some init-time action).
If you’d invest some time to prepare a PoC for this - we could consider this route.
@Slapbox based on the comment here I think this just isn’t solvable in the current API - middlewares (and you install
redux-saga
as a middleware) can’t listen for actions dispatched from store enhancers like that. Perhapsredux-saga
should have been a store enhancer and that could fix issues like this - but I’m not sure how safe changing this would be and what kind of unexpected problems we could end up with.