Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
redux-persist
Advanced tools
redux-persist is a library that allows you to save the Redux store in persistent storage, such as local storage, session storage, or even custom storage engines. This helps in maintaining the state of the application across page reloads.
Persisting Redux State
This feature allows you to persist the Redux state using a storage engine like local storage. The `persistReducer` function wraps your root reducer, and `persistStore` initializes the persistor.
const persistConfig = { key: 'root', storage }; const persistedReducer = persistReducer(persistConfig, rootReducer); const store = createStore(persistedReducer); const persistor = persistStore(store);
Rehydrating State
Rehydration is the process of loading the persisted state back into the Redux store when the application starts. This ensures that the state is restored to its previous state before the page was reloaded.
persistStore(store, null, () => { console.log('Rehydration complete'); });
Custom Storage Engines
You can use custom storage engines if the default local storage or session storage does not meet your requirements. This example shows how to create a noop storage engine for environments where local storage is not available.
import createWebStorage from 'redux-persist/lib/storage/createWebStorage'; const createNoopStorage = () => { return { getItem(_key) { return Promise.resolve(null); }, setItem(_key, value) { return Promise.resolve(value); }, removeItem(_key) { return Promise.resolve(); } }; }; const storage = typeof window !== 'undefined' ? createWebStorage('local') : createNoopStorage();
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.
Persist and rehydrate a redux store.
Redux Persist is performant, easy to implement, and easy to extend.
npm i redux-persist
Note: These docs apply to redux-persist v5. v4 will be supported for the forseeable future, and if it works well for your use case you are encouraged to stay on v4.
import { persistStore, persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/es/storage' // default: localStorage if web, AsyncStorage if react-native
import reducers from './reducers' // where reducers is a object of reducers
const config = {
key: 'root',
storage,
}
const reducer = persistCombineReducers(config, reducers)
function configureStore () {
// ...
let store = createStore(reducer)
let persistor = persistStore(store)
return { persistor, store }
}
Additionally if you are using react, it is recommended you use the provided PersistGate component for integration. This will take care of delaying the rendering of the app until rehydration is complete.
class App extends Component {
//...
render() {
return (
<PersistGate persistor={persistor}>
{/* rest of app */}
</PersistGate>
)
}
}
Additional Usage Examples:
There are three important breaking changes.
redux-persist-transform-immutable
will continue to operate as before as it works on substate, not top level state.Additionally v5 does not yet have typescript bindings.
WARNING v4 stored state is not compatible with v5. If you upgrade a v4 application, your users will lose their stored state upon upgrade. You can try the (highly) experimental v4 -> v5 state migration if you please. Feedback appreciated.
Standard Usage:
store.getState()
{REHYDRATE, PURGE}
) has moved to redux-persist/lib/constants
instead of redux-persist/constants
let reducer = persistCombineReducers(config, reducers)
key
is now required. Can be set to anything, e.g. 'primary'storage
is now required. For default storage: import storage from 'redux-persist/lib/storage'
Recommended Additions
import { PersistGate } from 'redux-persist/lib/integration/react'
config.debug = true
to get useful loggingIf your implementatation uses getStoredState + createPersistor see alternate migration
Long story short, the changes are required in order to support new use cases
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]
Persistence can now be nested, allowing for multiple persistoids with differing configuration to easily coexist.
import { combineReducers } from 'redux'
import { persistReducer } from 'redux-persist'
import session from 'redux-persist/lib/storage/session'
import localForage from 'localforage'
import { fooReducer, barReducer } from './reducers'
// foo state to be stored in localForage, but lets not persist someEmphemeralKey
const fooPersistConfig = {
key: 'foo',
storage: localForage,
blacklist: ['someEphemeralKey'],
}
// bar state should only last for the tab session
const barPersistConfig = {
key: 'bar',
storage: session,
}
let rootReducer = combineReducers({
foo: persistReducer(fooPersistConfig, fooReducer),
bar: persistReducer(barPersistConfig, barReducer),
})
Additionally depending on the mount point of persistReducer, you may not want to reconcile state at all.
import { hardSet } from 'redux-persist/lib/stateReconciler/hardSet'
//...
const fooConfig = {
key: 'foo',
storage: localForage,
stateReconciler: hardSet,
}
let reducer = combineReducer({
foo: persistReducer(fooConfig, fooReducer)
})
import getStoredStateMigrateV4 from 'redux-persist/lib/integration/getStoredStateMigratev4'
// ...
persistReducer({
// ...
getStoredState: getStoredStateMigrateV4(yourOldV4Config)
}, baseReducer)
import storage from 'redux-persist/lib/storage'
import sessionStorage from 'redux-persist/lib/storage/session'
import storage from 'redux-persist/lib/storage'
setItem
getItem
removeItem
. (NB: These methods must support promises)Transforms allow for arbitrary state transforms before saving and during rehydration.
import { createTransform, persistReducer } from 'redux-persist'
let myTransform = createTransform(
// transform state coming from redux on its way to being serialized and stored
(state, key) => specialSerialize(state, key),
// transform state coming from storage, on its way to be rehydrated into redux
(state, key) => specialDeserialize(state, key),
// configuration options
{whitelist: ['specialKey']}
)
const reducer = persistReducer({transforms: [myTransform]}, baseReducer)
FAQs
persist and rehydrate redux stores
The npm package redux-persist receives a total of 447,166 weekly downloads. As such, redux-persist popularity was classified as popular.
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.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.