I feel like I'm taking crazy pills when I see all these middlewares that encourage you to dispatch an action which emits other actions asynchronously. I think the async CAN (and maybe should?) be done before the store.
To me the benefit of Rx is that you can take an incoming stream of actions, map some of them to observables of other actions, and flatMap the entire result to get an ordered series of events. Then you can chain that resultant stream into the store by dispatching each event to it.
Not only does putting async inside of actions take the simple model of Redux and complicate it, but it means that as you time-travel debug - you may cause firing off of new AJAX requests (which can rewrite your history as you scrub?).
I guess I feel like putting the power of RxJS in front of the store makes plenty of sense to me, but I'm confused why a library to put it in side the store makes sense. I agree that Observables are a great model for Epics, but I wonder if Redux is being made to care about things that it should never know about.
Background: I've watched this video https://www.youtube.com/watch?v=AslncyG8whg, have been learning Rx for a few years, Redux half a year.
Store enhancers wrap around each other. Using Redux's compose
function, the enhancers passed to compose are ordered from right to left. So, if I use const storeEnhancer = compose(applyMiddleware(...middlewares), DevTools.instrument())
, the DevTools enhancer will wrap around the real store, and the middleware enhancer will wrap around the DevTools enhancer.
That means that time-travel debugging will only use actions that have gotten through all the middleware, and replaying those actions will not pass them through the middleware chain again. In other words, only actions that actually affected the store will be replayed.
The other thing to consider is that things like middleware allow access to the store's API for purposes of dispatching and checking state, and can be considered "inside" the store, but ultimately the key is that they are handled in a layer above the "real" store itself.
You may want to read Dan's excellent writeups on middleware and async behavior: How to dispatch a Redux action with a timeout? and Why do we need middleware for async flow in Redux? , which help clarify the reason for middleware, as well as the other links and explanations at http://redux.js.org/docs/FAQ.html#actions-side-effects .