Loading Partial Redux State
What if we could create a Redux store and then later, when other parts of the app load, add more reducers into the mix?
Don’t worry, my special friend. Articles like this start with rhetorical questions!
tl;dr
- Keep an inventory of your reducers.
- Use the store’s replaceReducer method.
- Example: github.com/reergymerej/partial-redux
Why
You’re lazy loading your app. You want to use one store, but you don’t know immediately all the possible state that it may hold. Maybe you’ve got some cool module system where modules define their reducers. Good for you!
What
You create your basic store with just the info you need up front. At runtime, you want to shoehorn in new reducers to further decorate the state.
How
When you create your store, add a reference to the different “slices” of state it’s got (aka, subreducers).
const store = createStore(
combineReducers({
foo: fooReducer,
bar: barReducer,
})
)
store.reducers = {
foo: fooReducer,
bar: barReducer,
}
OMG, it’s so redundant!
Yes, but combineReducers
doesn’t give us the original reducers. Bear with me.
Later that Day
When you feel like you need to augment your store, you can do it by simply replacing the reducer.
export const addReducer = (store, name, reducer) => {
store.reducers = {
...store.reducers,
[name]: reducer,
}
const combined = combineReducers(store.reducers)
store.replaceReducer(combined)
return store
}
store = addReducer(store, 'baz', bazReducer)
Here, we use that redundant reference we added to rebuild our reducers. Then we combine them and replace. Ding dong, magic!
Summary
If you’d like to play with this, check out github.com/reergymerej/partial-redux. It demonstrates adding/removing reducers at runtime. One cool/weird note is that you can dispatch events for a reducer prior to them being added and, once they are, they are synced up and reflect the state you expect.
If you read this far, I want you to know that you’re super cool and we would be best friends. Adios.