Skip to content

Instantly share code, notes, and snippets.

@michaelcontento
Created March 4, 2016 08:24
Show Gist options
  • Save michaelcontento/fa1cde84e982efe7b7e7 to your computer and use it in GitHub Desktop.
Save michaelcontento/fa1cde84e982efe7b7e7 to your computer and use it in GitHub Desktop.
Split state in redux-storage
import * as storage from 'redux-storage'
import filter from 'redux-storage-decorator-filter';
import { createStore, applyMiddleware } from 'redux';
// For this example I'm using a simple in-memory engine. Thus should obiously
// be repalced with something real :-)
function createEngine(name, value) {
return {
load() {
return Promise.resolve(value);
},
save(state) {
console.log(`${name} save:`, state);
return Promise.resolve();
}
};
}
// As we want to split the state into half and store them separatly, we need
// two engines. In the following lines we create our engine, decorate them
// so that they only work on their part of the state tree and finally convert
// them into a redux compatible middleware.
//
// NOTE: It's important that we use two different keys for the engines! If not
// they would overwrite each other.
// Primary stores everything EXCEPT the state.numbers
const primaryEngine = createEngine('primary', { user: { name: 'peter' } });
const primaryEngineFiltered = filter(primaryEngine, null, ['numbers']);
const primaryMiddleware = storage.createMiddleware(primaryEngineFiltered);
const primaryLoader = storage.createLoader(primaryEngine);
// Secondary stores ONLY state.numbers
const secondaryEngine = createEngine('secondary', { numbers: [1, 2, 3] });
const secondaryEngineFiltered = filter(secondaryEngine, ['numbers']);
const secondaryMiddleware = storage.createMiddleware(secondaryEngineFiltered);
const secondaryLoader = storage.createLoader(secondaryEngine);
// Now we're done with the redux-storage stuff and back to redux! For this
// example I just create a very simple reducer and hook everything together
const myReducer = (state, action) => {
if (action.type === 'add_number') {
state.numbers.push(action.payload);
}
return state;
};
const createStoreWithMiddleware = applyMiddleware(primaryMiddleware, secondaryMiddleware)(createStore);
const reducer = storage.reducer(myReducer);
const store = createStoreWithMiddleware(reducer);
// Everything is hooked up and we're ready to show how things work out :)
async function run() {
console.log('state on start', store.getState());
await primaryLoader(store);
console.log('state after primaryLoader', store.getState());
await secondaryLoader(store);
console.log('state after secondaryLoader', store.getState());
store.dispatch({ type: 'add_number', payload: 42 });
}
run()
.catch((error) => console.error('ERROR:', err))
.then(() => console.log('Done'));
state on start undefined
state after primaryLoader { user: { name: 'peter' } }
state after secondaryLoader { user: { name: 'peter' }, numbers: [ 1, 2, 3 ] }
secondary save: { numbers: [ 1, 2, 3, 42 ] }
primary save: { user: { name: 'peter' } }
Done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment