I\'m splitting my code based on components and I want to inject my reducers only when a component loads, rather than stacking them all up from the start in the store.
I
In react-router v4, for async injection of reducers, do the following:
In your reducer.js file add a function called createReducer that takes in the injectedReducers as arg and returns the combined reducer:
/**
* Creates the main reducer with the dynamically injected ones
*/
export default function createReducer(injectedReducers) {
return combineReducers({
route: routeReducer,
modal: modalReducer,
...injectedReducers,
});
}
Then, in your store.js file,
import createReducer from './reducers.js';
const store = createStore(
createReducer(),
initialState,
composedEnhancers
);
store.injectedReducers = {}; // Reducer registry
Now, in order to inject reducer in an async manner when your react container mounts, you need to use the injectReducer.js function in your container and then compose all the reducers along with connect. Example component Todo.js:
// example component
import { connect } from 'react-redux';
import { compose } from 'redux';
import injectReducer from 'filepath/injectReducer';
import { addToDo, starToDo } from 'containers/Todo/reducer';
class Todo extends React.Component {
// your component code here
}
const withConnect = connect(mapStateToProps, mapDispatchToProps);
const addToDoReducer = injectReducer({
key: 'todoList',
reducer: addToDo,
});
const starToDoReducer = injectReducer({
key: 'starredToDoList',
reducer: starToDo,
});
export default compose(
addToDoReducer,
starToDoReducer,
withConnect,
)(Todo);
React-Boilerplate is an excellent source for understanding this whole setup.You can generate a sample app within seconds. The code for injectReducer.js, configureStore.js( or store.js in your case) and in fact this whole configuration can be taken from react-boilerplate. Specific link can be found here for injectReducer.js, configureStore.js.