🗄 redux-persistence
Persistence layer for redux with flexible backends
Features
- Flexible storage engines
- indexedDb: based on window.indexedDb
- localStorage: based on window.localStorage
- Or for environments without
Promise
support localStorageFakePromise
- Or for environments without
- reactNativeAsyncStorage: based on
react-native/AsyncStorage
- remoteEndpoint: save/load via XHR
- Flexible state merger functions
- simple: merge plain old JS structures (default)
- immutablejs: merge plain old JS and Immutable objects
- Storage engines can be async
- Load and save actions that can be observed
{ type: 'REDUX_PERSISTENCE_SAVE', payload: /* state tree */ }
{ type: 'REDUX_PERSISTENCE_LOAD', payload: /* state tree */ }
- Various engine decorators
- Black- and whitelist actions from issuing a save operation
- Proper storage limit handling
- Typescript support out of the box
Usage
// Import redux and all your reducers as usual // We need to wrap the base reducer, as this is the place where the loaded// state will be injected.//// Note: The reducer does nothing special! It just listens for the LOAD// action and merge in the provided state :)// Note: A custom merger function can be passed as second argumentconst reducer = storage // Now it's time to decide which storage engine should be used//// Note: The arguments to `createEngine` are different for every engine!const engine = // And with the engine we can create our middleware function. The middleware// is responsible for calling `engine.save` with the current state afer// every dispatched action.//// Note: you can declare an action filtering function in the optionsconst middleware = storage // As everything is prepared, we can go ahead and combine all parts as usualconst createStoreWithMiddleware = createStoreconst store = // At this stage the whole system is in place and every action will trigger// a save operation.//// BUT (!) an existing old state HAS NOT been restored yet! It's up to you to// decide when this should happen. Most of the times you can/should do this// right after the store object has been created. // To load the previous state we create a loader function with our prepared// engine. The result is a function that can be used on any store object you// have at hand :)const load = storage // Notice that our load function will return a promise that can also be used// to respond to the restore event.
Details
redux-storage
This is a fork of The original library has issues as old as 2017. This library is meant to fix some of those while also providing out-of-the-box typescript support.
Engines, Decorators & Mergers
They all are published as own packages on npm. But as a convention all engines share the keyword redux-storage-engine, decorators can be found with redux-storage-decorator and mergers with redux-storage-merger. So it's pretty trivial to find all the additions to redux-storage you need 😄
Actions
redux-storage will trigger actions after every load or save operation from the underlying engine.
You can use this, for example, to display a loading screen until the old state has been restored like this:
{ }
Middleware
You can configure the middleware by passing a second argument to createMiddleware
.
filterAction
Return true
for any action that should be accepted by the middleware.
Example:
const blacklist = 'SOME_ACTION' 'SOME_OTHER_ACTION'
transform
Transform and return a new state before saving to the psrovided storage engine.
Example:
disableDispatchSaveAction
Don't dispatch a REDUX_PERSISTENCE_SAVE
action after saving to the provided storage engine, false
by default.
Example:
onError
Handle any errors thrown while trying to save to the provided storage engine.
Example: