Redux-persist: autoRehydrate does not lift the reducer it makes

Created on 28 Jun 2016  路  7Comments  路  Source: rt2zz/redux-persist

Finally found the root cause...

Problem:
if you use redux-devtools & call replaceReducer, the initial state overrides the persisted state.

Reason:
replaceReducer doesn't know about the reducerEnhancer that autoRehydrate() creates. That means the devtools inits without it, and doesn't merge the initial state with the persisted state.

Reproduction:
Call store.replaceReducer on an async route. (Probably works on sync routes, too. Haven't tried).

Workarounds:
None (use redux-storage?)

Fix:
Either offer a reducerEnhancer like redux-storage or lift the replaceReducer into the liftedStore. I think the former is cleaner because autoRehydrate does not need a lifted store, so using a higher-level API seems reasonable.

Most helpful comment

the latest version now lifts the reducer. I am using it in a HMR environment and it works. If there are outstanding issues please reopen!

All 7 comments

Can you point me to an example of how to lift replaceReducer?

I am hesitant to do a breaking api change of switching to a reducer enhancer.

Do you have an example of a reducerEnhancer @mattkrick ?
I've been battling with this, (And with async injection of reducers) I'd love to submit a PR :)

oh shoot, sorry i let this go dormant.
@rt2zz probably the easiest example I can think of is for something I wrote awhile back: https://github.com/mattkrick/redux-operations/blob/master/src/index.js#L257-L259

@fforres There are, to my knowledge, 3 reducer enhancers in the ecosystem: redux-storage, redux-optimistic-ui, and redux-undo

Ultimately, I went with redux-storage. I certainly can appreciate that breaking changes absolutely suck (going through react 15.2 woes right now 馃槖 ). I also know full well storeEnhancers make for a nicer developer experience than reducerEnhancers, but there's a high price to pay for that convenience, and I've had to defend redux-optimistic-ui from 2 PRs that wanted to do the same thing. For more discussion on the general topic, see https://github.com/mattkrick/redux-optimistic-ui/pull/12, and in the words of our almighty leader Dan: https://github.com/mattkrick/redux-optimistic-ui/pull/8#issuecomment-225016186

@mattkrick thanks for the reference now i understand what you mean by lifted reducer :)

I believe we can classify this as a bug, and fix by lifting the reducer in v3. For v4 I will reconsider the higher order reducer option.

redux-storage is a great choice as well, I am glad that worked out. Redux persist does a lot to be performant out of the box, hopefully after we get all of this sorted you can give it another try 馃憤

I did not come across this issue, has this been fixed?

the latest version now lifts the reducer. I am using it in a HMR environment and it works. If there are outstanding issues please reopen!

@rt2zz I may be misunderstanding something, but I'm not sure this issue is fixed. While it does work in a normal HMR env, it does not work when I am incognito mode and the network is throttled. By the same token, it doesn't work when I deploy my static site.

It seems to me that the reason is that there is a delay in the injection of the async reducer I am using (because of the network) and so the key is not present in the initial Redux state when autoRehydrate is called. Line 68 of autoRehydrate, if (!state.hasOwnProperty(key)) return; makes sure that the injected reducer is not hydrated, although, at least in this case, it should be. By removing this line, everything works as expected (rather as I expected, this may be intended).

Is there a specific reason why this line has to be called (by the way seems to be introduced in this commit)? If not I'll gladly make a PR!

By the way, love the package! Thank you!

Was this page helpful?
0 / 5 - 0 ratings