Redux-persist: [v5] Doesn't work with redux-observable epic middleware? (but does with thunk)

Created on 1 Nov 2017  路  2Comments  路  Source: rt2zz/redux-persist

Will try and provide as much info as I can. What I got down to was that swapping out epic middleware for thunk middleware made the persistence work (but then obviously not the rest of the app 馃槄 )

"react-native": "^0.48.4"
"redux-persist": "^5.2.2"
"redux-thunk": "^2.2.0" (only included to allow persist to work)
"redux-observable": "^0.17.0"

// rootEpic.js
import { combineEpics, createEpicMiddleware } from 'redux-observable'

const rootEpic = combineEpics(someWonderfulEpic)

const epicMiddleware = createEpicMiddleware(rootEpic)

export default epicMiddleware
// store.js
import storage from 'redux-persist/lib/storage'
import epicMiddleware from './rootEpic'
import { persistStore, persistCombineReducers } from 'redux-persist'
// plus other imports...

const persistReducerConfig = {
  key: 'root',
  storage
}

const reducer = persistCombineReducers(
  persistReducerConfig,
  reducers
)

export default () => {
  const initialState = {}

  const enhancers = composedEnhancers(applyMiddleware(epicMiddleware))
// key line ^^^
  const store = createStore(reducer, initialState, enhancers)
  const persistor = persistStore(store)

  return { store, persistor }
}
// App.js

const { store, persistor } = configureStore()

const Root = () => (
  <Provider store={store}>
    <PersistGate
      persistor={persistor}
      loading={<View><Text>LOADING</Text></View>}
    >
      <AppContainer />
    </PersistGate>
  </Provider>
)

When I reload the app (iOS), the PersistGate gets stuck in 'loading' state.

When I swap out epicMiddleware for thunk, the app loads as expected.

Any ideas? Please let me know if I can provide any more info or help at all.

Most helpful comment

hm I have not used epicMiddleware but I will comment on how redux-persist work and hopefully that narrows things down a bit:

  1. PERSIST action goes out with a register and rehydrate function attached
  2. persisted reducer picks up the action and starts rehydrating, this includes calling rehydrate which triggers a dispatch on the main store.
  3. REHYDRATE is handled to restore state, and then everything marks itself of rehydrated / bootstrapped at which point the gate is lifted.

If observable swallows PERSIST or REHYDRATE actions for any reason this flow will be short circuited. One thing that might help with debugging is to step through each action using redux-devtools and see where the hang happens.

All 2 comments

hm I have not used epicMiddleware but I will comment on how redux-persist work and hopefully that narrows things down a bit:

  1. PERSIST action goes out with a register and rehydrate function attached
  2. persisted reducer picks up the action and starts rehydrating, this includes calling rehydrate which triggers a dispatch on the main store.
  3. REHYDRATE is handled to restore state, and then everything marks itself of rehydrated / bootstrapped at which point the gate is lifted.

If observable swallows PERSIST or REHYDRATE actions for any reason this flow will be short circuited. One thing that might help with debugging is to step through each action using redux-devtools and see where the hang happens.

That's exactly it. I was listening to the REHYDRATE action to check authentication.

Apologies. Didn't think this would affect the persistence! Thanks.

Was this page helpful?
0 / 5 - 0 ratings