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

I know what I need to know.

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.