How to configure redux-persist with redux-toolkit?

17,923

Solution 1

store.js

import {configureStore} from '@reduxjs/toolkit';
import storage from 'redux-persist/lib/storage'
import {combineReducers} from "redux"; 
import { persistReducer } from 'redux-persist'
import thunk from 'redux-thunk'

const reducers = combineReducers({
 //...            
});

const persistConfig = {
    key: 'root',
    storage
};

const persistedReducer = persistReducer(persistConfig, reducers);


const store = configureStore({
    reducer: persistedReducer,
    devTools: process.env.NODE_ENV !== 'production',
    middleware: [thunk]
});

export default store;

Index/App.js

import store from './app/store';
import { PersistGate } from 'redux-persist/integration/react'
import { persistStore } from 'redux-persist'

let persistor = persistStore(store);

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

Solution 2

There's now a guide in the Redux Toolkit docs that will help you with this, as well as providing advice for purging the persisted state and working with RTK Query.

It also has some code you'll want to copy and paste to ignore the action types react-persist dispatches. This will stop it throwing error messages (I was getting the error A non-serializable value was detected in an action, in the path: `register`. when I ran my React Native app with Expo).

At time of writing, their code sample looks like this:

import { configureStore } from '@reduxjs/toolkit'
import {
  persistStore,
  persistReducer,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import { PersistGate } from 'redux-persist/integration/react'

import App from './App'
import rootReducer from './reducers'

const persistConfig = {
  key: 'root',
  version: 1,
  storage,
}

const persistedReducer = persistReducer(persistConfig, rootReducer)

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
})

let persistor = persistStore(store)

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
  document.getElementById('root')
)
Share:
17,923
Ashik
Author by

Ashik

I like to work with individuals that love the product we are making, putting a ton of effort to enhance what we are creating. I believe I am capable to accept new challenges and meet my employer's expectations. I use the Unix operating system for day-to-day development. Glad to work with: Javascript(ES6, and Beyond), Node/Express (Node.js web application framework) Database (MongoDB), react, redux.

Updated on June 26, 2022

Comments

  • Ashik
    Ashik almost 2 years

    I have configured redux-persist with a traditional react-redux setup like this:

    onst persistConfig = {
      key: 'root',
      storage,
      whitelist: ['todos'],
    };
    
    const persistedReducer = persistReducer(persistConfig, reducer);
    
    const store = createStore(
      persistedReducer,
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    );
    
    const persistor = persistStore(store);
    
    // wrapper
    const StateProvider = ({ children }) => {
      return (
        <Provider store={store}>
          <PersistGate loading={<div>Loading...</div>} persistor={persistor}>
            {children}
          </PersistGate>
        </Provider>
      );
    };
    

    But, how can I configure it with redux-toolkit? So far I have tried this:

    const persistedReducer = persistReducer(persistConfig, todoreducer);
    const store = configureStore({
      reducer: {
        todos: persistedReducer,
      },
    });
    
    const persistor = persistStore(store);
    
    // wrapper
    const StateProvider = ({ children }) => {
      return (
        <Provider store={store}>
          <PersistGate loading={<div>Loading...</div>} persistor={persistor}>
            {children}
          </PersistGate>
        </Provider>
      );
    };
    

    But, It is not working. I can't get the todos by const todos = useSelector(state => state.todos);

    it returns undefined.

  • S.Hashmi
    S.Hashmi over 2 years
    Very nice explanation.
  • Alqama Bin Sadiq
    Alqama Bin Sadiq about 2 years
    Just so you know, redux-thunk is already included by default when you use configureStore from redux toolkit so no need to include it again.
  • NIKHIL CHANDRA ROY
    NIKHIL CHANDRA ROY about 2 years
    This did not work for me on reduxjs-toolkit 1.8 / redux-persist 6.0.0. Following the guide in Redux Toolkit docs ( redux-toolkit.js.org/usage/usage-guide#use-with-redux-persis‌​t ) as recommended by @pipedreambomb worked out.
  • Kristiyan Tsvetanov
    Kristiyan Tsvetanov almost 2 years
    stackoverflow.com/a/69502876/4646232 says we don't need thunk as it is built in the redux toolkit.