![build](https://travis-ci.org/michaelcontento/redux-storage.svg)
Save and load the Redux state with ease.
Features
- Flexible storage engines
- Storage engines can be async
- Load and save actions that can be observed
- SAVE:
{ type: 'REDUX_STORAGE_SAVE', payload: /* state tree */ }
- LOAD:
{ type: 'REDUX_STORAGE_LOAD', payload: /* state tree */ }
- Various engine decorators
- Black- and whitelist actions from issuing a save operation
Installation
npm install --save redux-storage
Usage
import { createStore, applyMiddleware, combineReducers } from 'redux';
import * as reducers from './reducers';
const reducer = storage.reducer(combineReducers(reducers));
import createEngine from 'redux-storage/engines/reactNativeAsyncStorage';
const engine = createEngine('my-save-key');
const middleware = storage.createMiddleware(engine);
const createStoreWithMiddleware = applyMiddleware(middleware)(createStore);
const store = createStoreWithMiddleware(reducer);
const load = storage.createLoader(engine);
load(store);
load(store)
.then((newState) => console.log('Loaded state:', newState))
.catch(() => console.log('Failed to load previous state'));
Details
Engines
reactNativeAsyncStorage
This will use AsyncStorage
out of react-native.
import createEngine from 'redux-storage/engines/reactNativeAsyncStorage';
const engine = createEngine('my-save-key');
Warning: react-native is not a dependency of redux-storage! You
have to install it separately.
localStorage
Stores everything inside window.localStorage
.
import createEngine from 'redux-storage/engines/localStorage';
const engine = createEngine('my-save-key');
Warning: localStorage
does not expose a async API and every save/load
operation will block the JS thread!
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:
import { LOAD, SAVE } from 'redux-storage';
function storeageAwareReducer(state = { loaded: false }, action) {
switch (action.type) {
case LOAD:
return { ...state, loaded: true };
case SAVE:
console.log('Something has changed and written to disk!');
default:
return state;
}
}
Middleware
If you pass an array of action types as second argument to createMiddleware
,
those will be added to a internal blacklist and won't trigger calls to
engine.save
.
import storage from 'redux-storage'
import { APP_START } from './constants';
const middleware = storage.createMiddleware(engine, [ APP_START ]);
If you want to whitelist all actions that are allowed to issue a engine.save
,
just specify them as third argument.
import storage from 'redux-storage'
import { SHOULD_SAVE } from './constants';
const middleware = storage.createMiddleware(engine, [], [ SHOULD_SAVE ]);
Decorators
Decorators simply wrap your engine instance and modify/enhance it's behaviour.
Filter
Use this decorator to write only part of your state tree to disk.
import storage from 'redux-storage'
engine = storage.decorators.filter(engine, [
['some', 'key'],
['another', 'very', 'nested', 'key']
]);
Debounce
This decorator will delay the expensive save operation for the given ms. Every
new change to the state tree will reset the timeout!
import storage from 'redux-storage'
engine = storage.decorators.debounce(engine, 1500);
Immutablejs
Convert parts of the state tree into Immutable objects on engine.load
.
import storage from 'redux-storage'
engine = storage.decorators.immutablejs(engine, [
['immutablejs-reducer'],
['plain-object-reducer', 'with-immutablejs-key']
]);
Todo