You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For those unfamiliar, the code does essentially the following
// Returns a functionmiddleware(devtools(persistState(createStore)))
All the functions have the following structure
functionhigherOrderStore(next){return(reducer,initialState)=>{// manipulate reducer if neededconststore=next(manipulatedReducer,initialStore);// manipulate the store if neededreturn{
...store,// store overrides};};
It is generally a great API because it is simple, easy to understand and functional. Unfortunately, this API also has a major downside. It is not possible wrap store.dispatch and reducer when the user uses multiple higher order stores.
With compose the first function gets the first opportunity to receive reducer and wrap it in some way, but is the last to get store.dispatch. If you look at the above code, the higher order store is calling next(manipulatedReducer, initialStore).
This means reducer moves middleware -> devtools -> persistedState -> createStore. and store.dispatch moves middlewares <- devtools <-persistedState <- createStore. There is an issue when multiple higher order stores wrap the store.dispatch and the reducer.
For instance, devtools wraps all actions with extra data in the store.dispatch and then unwraps the action in the reducer. If another HOS wants to do the same thing, it is not possible because the wrapping and unwrapping needs to be in the same order. For example, if the HOS that is the last store to wrap the action and store.dispatcher, it needs to be the last store to wrap the reducer so it has the correct view of the actions entering the reducer.
The previous example shows that compose makes the store.dispatch and reducer wrapping go in opposite directions and that is an issue. I ran into this issue while implementing pseudo local state. In order to work around it, I have to turn the reducer into a weird dispatcher. That is definitely not the best solution.
Let's continue this discussion in #350. There's some discussion there already, and I'd like to consolidate it, as these problems will be solved together. (But thanks a lot for writing this up!)
In the
redux-devtools
and several other example repos, Redux higher order stores have been implemented in the following wayFor those unfamiliar, the code does essentially the following
All the functions have the following structure
It is generally a great API because it is simple, easy to understand and functional. Unfortunately, this API also has a major downside. It is not possible wrap
store.dispatch
andreducer
when the user uses multiple higher order stores.With
compose
the first function gets the first opportunity to receivereducer
and wrap it in some way, but is the last to getstore.dispatch
. If you look at the above code, the higher order store is callingnext(manipulatedReducer, initialStore)
.This means
reducer
movesmiddleware -> devtools -> persistedState -> createStore.
andstore.dispatch
movesmiddlewares <- devtools <-persistedState <- createStore
. There is an issue when multiple higher order stores wrap thestore.dispatch
and thereducer
.For instance, devtools wraps all actions with extra data in the
store.dispatch
and then unwraps the action in thereducer
. If another HOS wants to do the same thing, it is not possible because the wrapping and unwrapping needs to be in the same order. For example, if the HOS that is the last store to wrap the action andstore.dispatcher
, it needs to be the last store to wrap thereducer
so it has the correct view of the actions entering thereducer
.The previous example shows that
compose
makes thestore.dispatch
andreducer
wrapping go in opposite directions and that is an issue. I ran into this issue while implementing pseudo local state. In order to work around it, I have to turn thereducer
into a weird dispatcher. That is definitely not the best solution.https://github.com/taylorhakes/redux-devtools/blob/local-global-state/examples/todomvc/LocalState.js
I don't know the best solution to this, but one option would be to pass
store
instead ofcreateStore
to HOSs.That would depend on a change to the store API exposing the reducer. This following issue may help.
#350
The text was updated successfully, but these errors were encountered: