Hello.
Let's imagine that we have a reducer file like this:
export function something1 (state={}, action) {
switch (action.type) {
...
}
}
export function something2 (state={}, action) {
switch (action.type) {
...
}
}
There are also 3 other similar reducer files with multiple exports.
While the document merely gives an example how to use combineReducers with only 1 file with multiple exports - combineReducers | Redux (_import * as reducers from './reducers';_)
Then how do you use that function with multiple imports like this?
import * as reducers1 from './reducer1';
import * as reducers2 from './reducer2';
...
const reducer = combineReducers(???); // What argument to write. How to turn imports to object?
Thanks!
Imports _are_ object. Just like you'd merge two objects:
import * as reducers1 from './reducer1';
import * as reducers2 from './reducer2';
const allReducers = Object.assign({}, reducers1, reducers2);
const reducer = combineReducers(allReducers);
Thanks for such fast reply; didn't notice that ES6 has added such function. :+1:
I wonder if adding such thing to redux document would be worthwhile for in case if other would seek that?
@TheDeveloperXYZ
We're actually going to remove import *
from documentation and just show vanilla examples because it confuses a lot of people. See https://github.com/rackt/redux/pull/590.
Thanks for such fast reply; didn't notice that ES6 has added such function.
You can use something like Lodash's assign
if you don't want to include a polyfill, and already have Lodash or something similar. It's just merging objects; nothing magic. :-)
@gaearon Good idea to remove import *
. I'd also recommend at mentioning what destructuring statements and spread operators are in a comment the first time you use them.
Is it possible to multiple call combineReducers
?
If I use combineReducers
in separate file and then I want to attach one more reducer (actually, it is routerReducer
from react-router-redux
) is it possible to do?
The main issue that I cannot use spread operator (...reducers, routing: routerReducer
) only staged ES6 features.
The main issue that I cannot use spread operator (...reducers, routing: routerReducer) only staged ES6 features.
It just desugars to Object.assign({}, reducers, { routing: routerReducer })
. Object.assign()
is part of ES6 and you can use a polyfill for it.
You can even write a reasonable approximation by hand:
let finalReducers = {}
Object.keys(reducers).forEach(key => finalReducers[key] = reducers[key])
finalReducers.routing = routerReducer
const reducer = combineReducer(finalReducers)
It’s all just JavaScript!
Thanks for fast response!
I was trying to use Object.assign()
declaration before asking this question. In that case before combining I had rootReducer
object with property default: function combination()
which worked correctly. But after using var reducer = Object.assign({}, rootReducer, { routing: routerReducer })
my variable reducer
contained just a property routing: function routerReducer()
.
After combineReducer(finalReducers)
returned a function with routing but without my app reducers.
I guess I was doing something in a wrong way, but I can't understand what exactly.
But thank you very much about your approach with using Object.keys
If you see default
means you are importing an ES module with a CommonJS require
. This is usually a mistake. Please check out https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0 for some info on this.
If you can publish a project reproducing this I'm happy to take a look.
I do it like this:
mainReducer.js
import {combineReducers} from 'redux'
import {routerReducer} from 'react-router-redux'
// list of reducers
import registerReducer from 'registerReducer'
import homeReducer from 'homeReducer'
import aboutReducer from 'aboutReducer'
import contactUsReducer from 'contactUsReducer'
export const mapStateToProps = (state) => {
return {
register: state.register,
home: state.home,
about: state.about,
contact:state.contact
}
}
export default combineReducers({
routing: routerReducer,
register: registerReducer,
home: homeReducer,
about: aboutReducer,
contact: contactUsReducer
})
There is function mapStateToProps in there. The reason is because I often forgot to add entry to mapStateToProps function when it is put in other file. So I bring it to my main reducer,and for easy access. Open multiple files to make action and reducer is real pain.
Most helpful comment
Imports _are_ object. Just like you'd merge two objects: