Redux-persist: It doesn't work when Nested Persists combine with Hot Module Replacement

Created on 9 Dec 2018  Â·  4Comments  Â·  Source: rt2zz/redux-persist

Hi, @rt2zz
It doesn't work when Nested Persists combine with Hot Module Replacement.
I implement Nested Persists in my project. It works very well。
Recently, I need to use HMR, but I found only work first persist in Nested Persists.
Example

const rootPersistConfig = {
  key: 'root',
  blacklist: ['A']
}
const APersistConfig = {
  key: 'A'
}
const rootReducer = combineReducers({
  A: persistReducer(APersistConfig, AReducer),
  other: otherReducer,
})
persistReducer(rootPersistConfig, rootReducer)
...
if (module.hot) {
    module.hot.accept(() => {
      store.replaceReducer(
        persistReducer(rootPersistConfig, nextRootReducer)
      )
      store.persistor.persist()
    })
  }

I call persist() after calling store.replaceReducer. Other state be persisted after updated, but A state not be persisted after updated.
I found out by reading the source code that in the 108th line in the persistReducer.js file.

if (_persist) return state

The action is not propagated down, causing _paused in other persisters to be equal to true and not becoming false. I forked your project and changed the 108 line of code to

if (_persist)
  return {
        ...baseReducer(restState, action),
        _persist: { version, rehydrated: false },
  }

, and it worked. I am not sure if this change will cause other bugs. I want to know if there is a problem with the usage or a bug in the project itself.

bug report needs test repo v5

Most helpful comment

Can confirm that we are seeing this as well. I was looking for information about why only the first persistoid was working, and came across this. The last change that went in along with multiple nested reducers was us fixing hot module replacement...

All 4 comments

I am not sure if this change will cause other bugs. I want to know if there is a problem with the usage or a bug in the project itself.

I'm not sure either. @rt2zz might be able to help when he has time.

Can confirm that we are seeing this as well. I was looking for information about why only the first persistoid was working, and came across this. The last change that went in along with multiple nested reducers was us fixing hot module replacement...

Can confirm this. I am seeing this exact behavior using 5.10.0

Can confirm this same issue, albeit in a slightly different use-case: we use aggressive code splitting and dynamically attach & detach reducers as the user navigates to different views in our application. Some views have view-specific reducer state that needs to be persisted, so we use a nested setup similar to @nishino-tsukasa's example.

Even though persistor.persist() is always called after we swap out the reducers (store.replaceReducer() (related: #850)), this only resumes persistence at the top level; nested reducers never see the PERSIST action as it isn't propagated downwards due to this particular part of persistReducer:

if (_persist) return state

As a result, the nested reducers remain in the paused state indefinitely and no state for them is persisted.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

peteroid picture peteroid  Â·  4Comments

scic picture scic  Â·  3Comments

admbtlr picture admbtlr  Â·  3Comments

benmvp picture benmvp  Â·  3Comments

ssorallen picture ssorallen  Â·  4Comments