
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
redux-persist
Advanced tools
Persist and rehydrate a redux store.
npm install redux-persist
Usage Examples:
Basic usage involves adding persistReducer and persistStore to your setup. IMPORTANT Every app needs to decide how many levels of state they want to "merge". The default is 1 level. Please read through the state reconciler docs for more information.
// configureStore.js
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store, persistor }
}
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. NOTE the PersistGate loading prop can be null, or any react instance, e.g. loading={<Loading />}
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
persistReducer(config, reducer)key, storagewhitelist, blacklist, version, stateReconciler, debugcombineReducerspersistStore(store, [config, callback])persistStore, set the option manualPersist. Example: { manualPersist: true } Persistence can then be started at any point with peristor.persist(). You usually want to do this if your storage is not ready when the persistStore call is made.persistor object.purge()
.flush()
.pause()
.persist()
State reconcilers define how incoming state is merged in with initial state. It is critical to choose the right state reconciler for your state. There are three options that ship out of the box, let's look at how each operates:
import hardSet from 'redux-persist/lib/stateReconciler/hardSet')
This will hard set incoming state. This can be desirable in some cases where persistReducer is nested deeper in your reducer tree, or if you do not rely on initialState in your reducer.
{ foo: incomingFoo }{ foo: initialFoo, bar: initialBar }{ foo: incomingFoo } // note bar has been dropped{ foo: incomingFoo }{ foo: initialFoo, bar: initialBar }{ foo: incomingFoo, bar: initialBar } // note incomingFoo overwrites initialFooimport autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2')
This acts just like autoMergeLevel1, except it shallow merges two levels
{ foo: incomingFoo }{ foo: initialFoo, bar: initialBar }{ foo: mergedFoo, bar: initialBar } // note: initialFoo and incomingFoo are shallow mergedimport hardSet from 'redux-persist/lib/stateReconciler/hardSet'
const persistConfig = {
key: 'root',
storage,
stateReconciler: hardSet,
}
Redux persist ships with react integration as a convenience. The PersistGate component is the recommended way to delay rendering until persistence is complete. It works in one of two modes:
loading prop: The provided loading value will be rendered until persistence is complete at which point children will be rendered.bootstrapped argument. When bootstrapped is true, persistence is complete and it is safe to render the full app. This can be useful for adding transition animations.By Example:
// BLACKLIST
const persistConfig = {
key: 'root',
storage: storage,
blacklist: ['navigation'] // navigation will not be persisted
};
// WHITELIST
const persistConfig = {
key: 'root',
storage: storage,
whitelist: ['navigation'] // only navigation will be persisted
};
Nested persist can be useful for including different storage adapters, code splitting, or deep filtering. For example while blacklist and whitelist only work one level deep, but we can use a nested persist to blacklist a deeper value:
import { combineReducers } from 'redux'
import { persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import { authReducer, otherReducer } from './reducers'
const rootPersistConfig = {
key: 'root',
storage: storage,
blacklist: ['auth']
}
const authPersistConfig = {
key: 'auth',
storage: storage,
blacklist: ['somethingTemporary']
}
const rootReducer = combineReducers({
auth: persistReducer(authPersistConfig, authReducer),
other: otherReducer,
})
export default persistReducer(rootPersistConfig, rootReducer)
persistReducer has a general purpose "migrate" config which will be called after getting stored state but before actually reconciling with the reducer. It can be any function which takes state as an argument and returns a promise to return a new state object.
Redux Persist ships with createMigrate, which helps create a synchronous migration for moving from any version of stored state to the current state version. [Additional information]
Transforms allow you to customize the state object that gets persisted and rehydrated.
There are several libraries that tackle some of the common implementations for transforms.
When the state object gets persisted, it first gets serialized with JSON.stringify(). If parts of your state object are not mappable to JSON objects, the serialization process may transform these parts of your state in unexpected ways. For example, the javascript Set type does not exist in JSON. When you try to serialize a Set via JSON.stringify(), it gets converted to an empty object. Probably not what you want.
Below is a Transform that successfully persists a Set property, which simply converts it to an array and back. In this way, the Set gets converted to an Array, which is a recognized data structure in JSON. When pulled out of the persisted store, the array gets converted back to a Set before being saved to the redux store.
import { createTransform } from 'redux-persist';
const SetTransform = createTransform(
// transform state on its way to being serialized and persisted.
(inboundState, key) => {
// convert mySet to an Array.
return { ...inboundState, mySet: [...inboundState.mySet] };
},
// transform state being rehydrated
(outboundState, key) => {
// convert mySet back to a Set.
return { ...outboundState, mySet: new Set(outboundState.mySet) };
},
// define which reducers this transform gets called for.
{ whitelist: ['someReducer'] }
);
export default SetTransform;
The createTransform function takes three parameters.
In order to take effect transforms need to be added to a PersistReducer’s config object.
import storage from 'redux-persist/lib/storage';
import { SetTransform } from './transforms';
const persistConfig = {
key: 'root',
storage: storage,
transforms: [SetTransform]
};
import storage from 'redux-persist/lib/storage'import storageSession from 'redux-persist/lib/storage/session'import AsyncStorage from '@react-native-community/async-storage'setItem getItem removeItem. (NB: These methods must support promises) #redux-persist channel in the Reactiflux Discord
redux-localstorage is another library that allows you to persist Redux state to local storage. It is similar to redux-persist but offers a more modular approach, allowing you to choose different storage adapters and serializers.
redux-persist-transform-encrypt is a transformer for redux-persist that encrypts your persisted state. This is useful if you need to store sensitive information securely. It works as an add-on to redux-persist, providing encryption capabilities.
redux-persist-cookie-storage is a storage engine for redux-persist that uses cookies instead of local storage or session storage. This can be useful for server-side rendering or when you need to share state across different subdomains.
FAQs
persist and rehydrate redux stores
We found that redux-persist demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.