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
or
yarn add redux-persist
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}
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:
- blacklist:
example:
// BLACKLIST
const persistConfig = {
key: 'root',
storage: storage,
blacklist: ['navigation'] // navigation will not be persisted
};
- whitelist:
example:
// WHITELIST
const persistConfig = {
key: 'root',
storage: storage,
whitelist: ['navigation'] // only navigation will be persisted
};
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>
);
};
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
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.
Top comments (16)
Just a quick note, you pass the persistReducer instead of your newly created persistedReducer here:
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 bepersistedReducer
, notpersistReducer
...Is it true ?
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).
Dispatch your action only after verification
so Great article
tnx alot bro
Glad to help buddy! 😁
Can we change the default storage of redux persist to sessionStorage instead of localStorage?
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?
+1 on that
github.com/rt2zz/redux-persist?tab...
@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...
thanks alot! was very helpfull!
My Pleasure buddy! 😁
I'm dispatching a user details, and everything is been saved into local storage, is that not dangerous??
Thanks a lot
My pleasure!