I'm going migrate to Redux.
My application consists of a lot of parts (pages, components) so I want to create many reducers. Redux examples show that I should use combineReducers()
to generate one reducer.
Also as I understand Redux application should have one store and it is created once the application starts. When the store is being created I should pass my combined reducer. This makes sense if the application is not too big.
But what if I build more than one JavaScript bundle? For example, each page of application has own bundle. I think in this case the one combined reducer is not good. I looked through the sources of Redux and I have found replaceReducer()
function. It seems to be what I want.
I could create combined reducer for each part my application and use replaceReducer()
when I move between parts of application.
Is this a good approach?
As of October 2017:
Reedux
implements what Dan suggested and nothing more, without touching your store, your project or your habits
There are other libraries too but they might have too many dependencies, less examples, complicated usage, are incompatible with some middlewares or require you to rewrite your state management. Copied from Reedux's intro page:
There is now a module that adds injecting reducers into the redux store. It is called Redux Injector. https://github.com/randallknutson/redux-injector
Here is how to use it:
Do not combine reducers. Instead put them in a (nested) object of functions as you would normally but without combining them.
Use createInjectStore from redux-injector instead of createStore from redux.
Inject new reducers with injectReducer.
Here is an example:
Full Disclosure: I am the creator of the module.
We released a new library that helps modulating a Redux app and allows dynamically adding/removing Reducers and middlewares.
Please take a look at https://github.com/Microsoft/redux-dynamic-modules
Modules provide the following benefits:
Modules can be easily re-used across the application, or between multiple similar applications.
Components declare the modules needed by them and redux-dynamic-modules ensures that the module is loaded for the component.
Features
Example Scenarios
Here is another example with code splitting and redux stores, pretty simple & elegant in my opinion. I think it may be quite useful for those who are looking for a working solution.
This store is a bit simplified it doesn't force you to have a namespace (reducer.name) in your state object, of course there may be a collision with names but you can control this by creating a naming convention for your reducers and it should be fine.
This is how I implemented it in a current app (based on code by Dan from a GitHub issue!)
Create a registry instance when bootstrapping your app, passing in reducers which will be included in the entry bundle:
Then when configuring the store and routes, use a function which you can give the reducer registry to:
Where these functions look something like:
Here's a basic live example which was created with this setup, and its source:
It also covers the necessary configuration to enable hot reloading for all your reducers.
This is not a full answer but should help you get started. Note that I'm not throwing away old reducers—I'm just adding new ones to the combination list. I see no reason to throw away the old reducers—even in the largest app you're unlikely to have thousands of dynamic modules, which is the point where you might want to disconnect some reducers in your application.
reducers.js
store.js
routes.js
There may be neater way of expressing this—I'm just showing the idea.