Joe Half Face
Joe Half Face

Reputation: 2333

Nesting `combineReducers` doesn't let to have state without nested objects

I have bookManageReducer.jsx:

import { combineReducers } from 'redux'
import {
  REQUEST_BOOKS_PAGE,
  RECEIVE_BOOKS_PAGE
} from '../constants/dashboardConstants'

const books = (state = [], action) => {
  switch (action.type) {
    case RECEIVE_BOOKS_PAGE:
      return action.books
    default:
      return state
  }
}

const booksState = (state = {isFetching: false}, action) => {
  switch (action.type) {
    case REQUEST_BOOKS_PAGE:
      return {isFetching: true}
    case RECEIVE_BOOKS_PAGE:
      return {isFetching: true}
    default:
      return state
  }
}
// ...
const booksManageReducer = combineReducers({ books, employees, employeesList, booksPagination, booksState })

export default booksManageReducer

What I want is to combine all intermediate reducers in root reducer dashboardReducer.jsx:

import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'
import booksManageReducer from './booksManageReducer'

const companyId = (state = {}, action) => {
  return state
}

const dashboardReducer = combineReducers({booksManageReducer, companyId, routing: routerReducer})

export default dashboardReducer

Which produce this state:

Object {booksManageReducer: Object, companyId: 1, routing: Object}

instead of

Object {books: [], ..., companyId: 1, routing: Object}

When I try to use object spread operator:

const dashboardReducer = combineReducers({
    ...booksManageReducer, companyId, routing: routerReducer
})

It just disappears from the state, and Object.assign doesn't work either.

Upvotes: 2

Views: 2269

Answers (1)

Andrew Li
Andrew Li

Reputation: 57944

Don't combine them into booksMangeReducer. Instead, just export them all as named exports and combine all the reducers at once:

export { 
  books, 
  employees, 
  employeesList, 
  booksPagination, 
  booksState 
};

Then import them all:

import { 
  books, 
  employees, 
  employeesList, 
  booksPagination, 
  booksState 
} from './booksManageReducer'

Then combine them all individually with combineReducers:

combineReducers({
  books, 
  employees, 
  employeesList, 
  booksPagination, 
  booksState,
  companyId,
  routing: routerReducer
});

combineReducers uses the keys of the passed object to construct state. This will give the desired hierarchy.

Another way which is similar to what you're doing could be exporting an object containing all the reducers themselves, then import the object and spreading it:

export default {
    //books, employees, etc.
};

Then:

import reducers from './booksManageReducer';

Finally:

combineReducers({
  ...reducers,
  companyId,
  routing: routerReducer
});

Upvotes: 5

Related Questions