0

After updating most packages in my react project, I can no longer figure out what changed to make redux-persist work when using connected-react-router (updated from react-redux-router which is now deprecated).

I've tried looking at guides online but none seem to integrate redux-persist with connected-react-router. How would I go about using the new connected-react-router with a setup like this?

package versions:

├── connected-react-router@6.6.0 
├── react@16.12.0 
├── react-redux@6.0.1 
└── redux-persist@6.0.0 

src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './css/index.css';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
import { PersistGate } from 'redux-persist/integration/react'
import createHistory from 'history/createBrowserHistory'
import { ConnectedRouter } from 'connected-react-router'
import { Provider } from 'react-redux'
import configureStore from './store'

const history = createHistory();
const store = configureStore(history);

ReactDOM.render((
    <Provider store={store}>
        <ConnectedRouter history={history}>
            <App/>
        </ConnectedRouter>
    </Provider>
), document.getElementById('root'));    
registerServiceWorker();

src/store.js:

import { applyMiddleware, createStore, compose } from 'redux'
import { createFilter   } from 'redux-persist-transform-filter';
import { persistReducer, persistStore } from 'redux-persist'
import { routerMiddleware } from 'connected-react-router'
import thunk from "redux-thunk";
import storage from 'redux-persist/lib/storage'
import apiMiddleware from './middleware';
import rootReducer from './reducers'
import createRootReducer from './reducers'


export default (history) => {
    const persistedFilter = createFilter(
        'auth', ['access', 'refresh']
    );

    const reducer = persistReducer(
        {
            key: 'root',
            storage: storage,
            whitelist: ['auth', 'user', 'game'],
            transforms: [ persistedFilter]
        },
        rootReducer
    );

    const store = createStore(
        createRootReducer(history), {},
        compose(
            applyMiddleware(thunk, apiMiddleware, routerMiddleware(history)),
            window.devToolsExtension ? window.devToolsExtension() : f => f,
        ),
    );
    persistStore(store);
    return store;
}

src/reducers/index.js:

import { combineReducers } from 'redux'
import { connectRouter } from 'connected-react-router'
import auth, * as fromAuth from './auth'
import { reducer as form  } from 'redux-form';

const createRootReducer = (history) => combineReducers({
    router: connectRouter(history),
    auth: auth,
    // other reducer stuff
});
export default createRootReducer
cclloyd
  • 8,171
  • 16
  • 57
  • 104

1 Answers1

0

One thing to check, it could have something to do with PersistGate?

In your src/index.js, you are importing PersistGate, but not using it.

import { PersistGate } from 'redux-persist/integration/react'

Try using it by wrapping your root component with PersistGate. i.e. like this.

<Provider store={store}>
  <PersistGate loading={null} persistor={persistor}>
    <ConnectedRouter history={history}>
      <App/>
    </ConnectedRouter>
  </PersistGate>
</Provider>

To do that, you'll need access to persistor which is something you'll need to define when you call persistStore(store). i.e. some minor refactoring of your src/store.js will be required.

Further information about this is found in the doc for redux-persist. It says...

If you are using react, wrap your root component with PersistGate. This delays the rendering of your app's UI until your persisted state has been retrieved and saved to redux.

Danoz
  • 977
  • 13
  • 24