2
votes

Error: Reducer "assetsReducer" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.

In my ReactJS app I have 2 reducers/actions (assets and board).

In my store.ts file I use combineReducers like so:

import { applyMiddleware, createStore, combineReducers } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import thunkMiddleware from 'redux-thunk'

import { IinitialState } from './shared/types'
// import reducer from './reducers/assets/'
import assetsReducer from './reducers/assets'
import boardReducer from './reducers/board'

const rootReducer = combineReducers({
  assetsReducer,
  boardReducer
});

export const defaultInitialState = {
  assets: [],
  portfolio: [],
  loading: false,
  overlay: false
};

console.log('rootReducer', rootReducer);

export function initializeStore(initialState: IinitialState = defaultInitialState) {
  return createStore(
    rootReducer,
    initialState,
    composeWithDevTools(applyMiddleware(thunkMiddleware))
  )
}

This should be correct, yet I get the following typescript error, and the console error above when I refresh my app on localhost.

Type 'IinitialState' has no properties in common with type 

'DeepPartial<{ assetsReducer: { assets: any; loading: boolean; portfolio: never[]; overlay: boolean; }; boardReducer: { overlay: any; assets: never[]; portfolio: never[]; loading: boolean; }; }>'.ts(2559)

enter image description here


assetsReducer:

import { Actions } from '../actions/assets'
import { defaultInitialState } from '../store'

export default (state = defaultInitialState, action: any) => {
  switch (action.type) {
    case Actions.GET_ALL_ASSETS: {
      const { assets } = action;
      return {
        ...state,
        assets,
        loading: false
      };
    }

    default:
      return state;
  }
};

boardReducer

import { Actions } from '../actions/board'
import { defaultInitialState } from '../store'

export default (state = defaultInitialState, action: any) => {
  switch (action.type) {
    case Actions.SET_OVERLAY_STATE: {
      const { overlay } = action;
      return {
        ...state,
        overlay
      };
    }

    default:
      return state;
  }
};
2
What does assetsReducer look like?markerikson
@markerikson just added both!Leon Gaban

2 Answers

2
votes

Your initial state is incorrect. You initial state should look something like this:

export const defaultInitialState = {
  assetsReducer: {assets: [], loading: false, portfolio: [], overlay: false},
  boardReducer: {assets: [], loading: false, portfolio: [], overlay: false},
}

More information on this can be found in the Redux Docs

1
votes

Beyond the other reply, it looks like you have a circular reference issue.

store.ts imports assetsReducer.ts, but assetsReducer tries to import store to get its initial default state value.

Therefore, when assetsReducer.ts loads, store.ts hasn't finished evaluating, and defaultInitialState is undefined.

You should reorganize things so that you don't have circular references any more. The simplest approach is to have assetsReducer.ts define its own initial state value (and export it separately if it needs to be referenced elsewhere).