Created
March 4, 2016 08:24
-
-
Save michaelcontento/fa1cde84e982efe7b7e7 to your computer and use it in GitHub Desktop.
Split state in redux-storage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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