Raphael Parreira Raphael Parreira - 1 month ago 7
React JSX Question

How to merge multiple reducers inside one state?

I'm trying to build an app that has

two or more
reducers "answering" by one object inside my
storeState
.

Example:

storeState {
app: {...},
comments: [ ...two or more states inside one... ]
}


I already tried the following using combineReducers that didn't work, my
comments
state became an empty object.

import { combineReducers } from 'redux';
import commentFacebookReducer from './twitch';
import commentYoutubeReducer from './reddit';
import appReducer from './app';

const rootReducer = combineReducers({
comments: [commentFacebookReducer, commentYoutubeReducer],
app: appReducer
});

export default rootReducer;


And I already tried to combine my comment reducers before combine them in
rootReducer
:

import { combineReducers } from 'redux';
import commentFacebookReducer from './twitch';
import commentYoutubeReducer from './reddit';
import appReducer from './app';

const commentReducers = combineReducers({
commentFacebookReducer,
commentYoutubeReducer
});

const rootReducer = combineReducers({
comments: commentReducers,
app: appReducer
});

export default rootReducer;


But it gives me a storeState like the following. But I need a state that is an array of comments, I can't deal with these reducers names (like commentFacebookReducer or commentYoutubeReducer), because I'll have thousands of reducers like these.

storeState {
app: {...},
comments: {
commentFacebookReducer: {...},
commentYoutubeReducer: {...}
}
}

Answer Source

I dont think you can do that by just using combineReducer. Because combineReducer expects an object and each property of that object should be a function. Then each function in that object makes an individual property in redux state tree and the value of that property is the value returned by that function (When any action is dispatched).

Also you cannot access one reducer's state in other reducer, because redux only pass that particular reducer's state to the function. That means you cannot get/alter state of commentFacebookReducer inside commentYoutubeReducer.

The only better solution i can think of right now is that you combine them when you are using them (most probably in mapStateToProps). You keep your reducer as you are doing like this:

const commentReducers = combineReducers({
  commentFacebookReducer,
  commentYoutubeReducer
});

const rootReducer = combineReducers({
  comments: commentReducers,
  app: appReducer
});

Now all our comments are in a single object i.e.(state.comments). Now in mapStateToProp you do something like this to combine them in single object::

const mapStateToProps = state => {
    return {
        comments: Object.keys(state.comments).reduce((d, k) => {return d.concat(a[k])}, [] )
    };
};

Now in component, you can simply access them as single array using this.props.comments