redux-persist: [v5] PersistGate never renders because rehydrate never gets called

I’m trying redux-persist for the first time, but can’t get my normal render through PersistGate.

function createPersistentStore ( persistenceKey ) {
    const persistConfig = {
        key: persistenceKey,
        storage,
    };

    /***** APP REDUCER *****/
    const appReducer = persistCombineReducers( persistConfig, reducerConfig );

    /***** STORE *****/
    const store = createStore( appReducer, undefined, applyMiddleware( thunk ) );
    const persistor = persistStore( store );

    return {
        persistor,
        store
    };
}

const { store, persistor } = createPersistentStore( 'foo' );

function onBeforeLift () {
    // take some action before the gate lifts
}

export default class App extends React.Component {
    render() {
        return (
            <Provider store={ store } >
                <PersistGate
                    loading={ null }
                    onBeforeLift={ onBeforeLift }
                    persistor={ persistor }>
                    <Loaded />
                </PersistGate>
            </Provider>
        );
    }
}

const Loaded = () => {
    console.log( 'loaded' );
    return ( <View><Text>loaded</Text></View> );
};

The page is blank and loaded is never logged.

When this code runs in persistStore.js, it dispatches to reducers that are props of the reducerConfig that I passed to persistCombineReducers(), but rehydrate() is never called:

  persistor.persist = function () {
    store.dispatch({ type: _constants.PERSIST, register: register, rehydrate: rehydrate });
  };

Is there more I have to do that is not documented in the readme? Do I need to handle the PERSIST action myself and call rehydrate myself?

Thanks, Matt

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 5
  • Comments: 19 (4 by maintainers)

Most upvoted comments

This is a really ugly issue that I had in v4 already and now I upgraded to v5 and it is still the case. Easy way to reproduce:

  1. Put a debugger breakpoint in your main App.js render function.
  2. Reload after PERSIST and before REHYDRATE action
  3. REHYDRATE wille never be called again until you kill the app an restart it

In my case updating to the latest versions didn’t help me. The app stops working at some moment, rehydrade/persist action never calls, nothing helps except killing the emulator and re-start the react-native. Is it possible to call rehydrate action without PersistGate? Or any other solutions would be good. Thanks!

FYI we are currently contemplating adding timeout in this PR #702

That would at least give users some recourse (without the need to switch storage adapters)

So given the issue is in the underlying storage layer, I think the only remedy redux-persist can offer is a timeout config that will set a max time for rehydration before giving up.

Also I would recommend considering an alternative storage adapter, e.g. https://github.com/robwalkerco/redux-persist-filesystem-storage

I am not clear what exactly the issue is can you restate the entirety of the problem?

@henrytao-me you are saying you see rehydrated === false even after rehydration completes ocassionally?

Try to define your persistor inside component constructor :

import store from './store';

class App extends Component {
  constructor() {
    super();
    this.persistor = persistStore(store);
  }
  render() {

    return (
      <Provider store={store}>
        <PersistGate persistor={this.persistor} loading={null}>
          <RootRouter />
        </PersistGate>
      </Provider>
    )
  }
}

@nenti There is an issue here for your reference. https://github.com/facebook/react-native/issues/14101

I haven’t encounter this issue (at least as often as I notice) since I use this

    "react": "16.0.0",
    "react-native": "0.51.0",
    "react-redux": "5.0.6",