DEV Community

Vikrant Bhat
Vikrant Bhat

Posted on

Redux-persist (v6) in detail (React)

Persistense is the key to success

Whenever you reload your app, the javascript process has nothing in memory. You will have to re-initialize state, and maybe set some basic state based on the url (if you are in a browser). Though usually this is what you want but there are many use cases where you might want to persist your redux state even when you reload your browser window.

This idea of persisting state across refresh in web applications that use redux for global state management can be achieved using the redux-persist npm package.

The complete redux-store or some specific part of it can be persisted in the browser localstorage easily!

A very common use case for implementing redux-persist in 2020 is:

Offline First. Many users may not have stable internet connection. Persistence is the first step of offline support.

Okay so that's it for the introduction, now let's set up redux-persist in our react-redux application.

Check this out for setting up a react-redux app
or clone this repo


Step 1 - Install redux-persist

npm install redux-persist
Enter fullscreen mode Exit fullscreen mode

or

yarn add redux-persist
Enter fullscreen mode Exit fullscreen mode

Step 2 - Configure redux-store

// store.js

import { createStore, applyMiddleware } from 'redux'
import { persistStore, persistReducer } from 'redux-persist' // imports from redux-persist
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web

import rootReducer from './reducers' // Root reducer

const persistConfig = { // configuration object for redux-persist
    key: 'root',
    storage, // define which storage to use
}

const persistedReducer = persistReducer(persistConfig, rootReducer) // create a persisted reducer

const store = createStore(
    persistReducer, // pass the persisted reducer instead of rootReducer to createStore
    applyMiddleware() // add any middlewares here
)

const  persistor = persistStore(store); // used to create the persisted store, persistor will be used in the next step

export {store, persistor}
Enter fullscreen mode Exit fullscreen mode

The persistConfig object needs key and storage to work properly since they are mandatory, but it can also take some other key value pairs for more customization, some of them are:

  1. blacklist:
example:
// BLACKLIST
const persistConfig = {
  key: 'root',
  storage: storage,
  blacklist: ['navigation'] // navigation will not be persisted
};
Enter fullscreen mode Exit fullscreen mode
  1. whitelist:
example:
// WHITELIST
const persistConfig = {
  key: 'root',
  storage: storage,
  whitelist: ['navigation'] // only navigation will be persisted
};
Enter fullscreen mode Exit fullscreen mode

Note: if you are using react native then your persistConfig will look like this (see docs):

import AsyncStorage from '@react-native-community/async-storage';

const persistConfig = {
    >       key: 'root',
    >       storage: AsyncStorage
    >}

Step 3 - Wrap your root component with PersistGate

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

NOTE the PersistGate's loading prop can alse be null, or any react instance, e.g. loading={<Loading />}
i.e it can be any react component, so you can add your custom loader as a component here.
If null is provided as a value then it simply loads nothing until persisted state is retrieved. (Don't worry if you don't have a custom loader yet, it hardly takes fraction of a second to retrieve a simple redux state)

import {store, persistor} from './redux/store'
import { PersistGate } from 'redux-persist/integration/react'

const App = () => {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}> // null passed to loading, persistor is being used here
        <RootComponent />
      </PersistGate>
    </Provider>
  );
};
Enter fullscreen mode Exit fullscreen mode



Congratulations! You have successfully completed the setup of redux-persist in your react-app! It was fairly easy wasn't it? Let me know your thoughts on twitter


Additional resources

  1. Check out this great article to know how you can do versioning in your persisted localstorage using redux-persist. This usually comes in handy when you make some big changes in your redux state and its not compatible with the previously saved localstorage in production, so redux-persist has this good to have feature for versioning built in.


    enter image description here

  2. Docs

  3. API

  4. How to setup Redux with React (2020)

Top comments (16)

Collapse
 
deepseafishdev profile image
DeepSeaFish-Dev

Just a quick note, you pass the persistReducer instead of your newly created persistedReducer here:

const store = createStore(
    persistReducer, // pass the persisted reducer instead of rootReducer to createStore
    applyMiddleware() // add any middlewares here
)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gajen007 profile image
Gajen Dissanayake

Thanks Bro,

I assumed there is a typo mistake in Step 2

//pass the persisted reducer instead of rootReducer to createStore//

So the first argument of configureStore method should be persistedReducer, not persistReducer...

Is it true ?

Collapse
 
ssameghini profile image
Sebastián Sameghini

Hi!
What if I only want to persist the store after a user has authenticated?
For example, when someone visits my page an authentication check is made (token then session restored), but if no session is found, the page redirects to /login. PersistGate would delay the rendering of this page until a persist process completes, preventing anyone without credentials to access the page (in practice, no one access).

Collapse
 
bhatvikrant profile image
Vikrant Bhat

Dispatch your action only after verification

Collapse
 
zahirhasheminas profile image
zahir hashemi nasab

so Great article
tnx alot bro

Collapse
 
bhatvikrant profile image
Vikrant Bhat

Glad to help buddy! 😁

Collapse
 
abhishek150190 profile image
Abhishek150190

Can we change the default storage of redux persist to sessionStorage instead of localStorage?

Collapse
 
tmitkov profile image
Tihomir Mitkov

Wouldn't this be useless? I mean the sessionStorage gets cleared when the tab gets closed, the same behaviour would occure if you simply use redux without redux-persist?

Collapse
 
bhatvikrant profile image
Vikrant Bhat

+1 on that

Collapse
 
daniilryb profile image
Daniil Rybakov
Collapse
 
hamzaazeem97 profile image
HamzaAzeem97

@bhatvikrant I will assume you guru in redux persist, if you solve this issue. Im stuck for 2 Months. Plz Help
stackoverflow.com/questions/695872...

Collapse
 
davidromanhub profile image
David Roman

thanks alot! was very helpfull!

Collapse
 
bhatvikrant profile image
Vikrant Bhat

My Pleasure buddy! 😁

Collapse
 
halltech profile image
Olajide Ayomide

I'm dispatching a user details, and everything is been saved into local storage, is that not dangerous??

Collapse
 
moataz0 profile image
Moataz0

Thanks a lot

Collapse
 
bhatvikrant profile image
Vikrant Bhat

My pleasure!