Bagus Trihatmaja
Bagus Trihatmaja

Reputation: 865

Nested state with the same name

I am implementing react with redux and I got a nested state with the same name (See picture)

enter image description here

Here is my reducer:

function helps(state = {
  isFetching: false,
  items: []
}, action) {
  switch (action.type) {
    case types.HELPS_FEED_REQUEST:
      return Object.assign({}, state, {
        isFetching: true
      });
    case types.HELPS_FEED_SUCCESS:
      return Object.assign({}, state, {
        isFetching: false,
        items: [
          ...state.items,
          ...action.items
        ]
      });
    default:
      return state;
  }
}

const rootReducer = combineReducers({
  helps
});

export default rootReducer;

the index.js reducer:

import {combineReducers} from 'redux';
import help from './helpReducer';
import helps from './helpsReducer';


const rootReducer = combineReducers({
    help,
    helps
});

export default rootReducer;

My question is: Why I don't have only one "helps" state with isFetching and items? Is there something obvious that I am missing?

EDIT:

Apparently, it is because of I am using combine reducer. So if I change the name of the function to, for example helps_feed, the state will be:

helps
-- helps_feed

Why does combineReducers make a nested state?

configureStore.js

import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from '../reducers';
import createSagaMiddleware, {END} from 'redux-saga';
import helpSagas from '../sagas/helpSaga';

export default function configureStore(initialState) {
  const rootSagas = [
    helpSagas
  ];
  const sagaMiddleWare = createSagaMiddleware();

  const store = createStore(
    rootReducer,
    initialState,
    compose(
      applyMiddleware(sagaMiddleWare),
      window.devToolsExtension ? window.devToolsExtension() : f => f
  ));

  store.runSaga = sagaMiddleWare.run(...rootSagas);
  store.close = () => store.dispatch(END);
  return store;
}

Upvotes: 1

Views: 910

Answers (1)

QoP
QoP

Reputation: 28397

combineReducers creates a new object with the reducers you pass to it, that's the reason you got your states nested.

To fix it export the reducer without using combineReducers since you are not combining any reducers.

function helps(state = {
  isFetching: false,
  items: []
}, action) {
  switch (action.type) {
    case types.HELPS_FEED_REQUEST:
      return Object.assign({}, state, {
        isFetching: true
      });
    case types.HELPS_FEED_SUCCESS:
      return Object.assign({}, state, {
        isFetching: false,
        items: [
          ...state.items,
          ...action.items
        ]
      });
    default:
      return state;
  }
}

export default helps;

Scenario with multiple combineReducers.

rootReducer.js

import auth from './auth'
import trainer from './trainer/trainerReducer'
import athlete from './athlete/athleteReducer'

const rootReducer = combineReducers({
    auth,
    trainer,
    athlete
});

trainerReducer.js

import { combineReducers } from 'redux'
import manageAthletes from './manageAthletes'
import manageRoutines from './manageRoutines'

const trainerReducer = combineReducers({
    manageRoutines,
    manageAthletes
});

export default trainerReducer;

athleteReducer

import trainer from './trainer'
import routine from './routine'

const athleteReducer = combineReducers({
    trainer,
    routine
});

export default athleteReducer;

Upvotes: 2

Related Questions