Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get “Reducer [...] returned undefined during initialization” despite providing initialState to createStore()?

I had set InitialState in my redux createStore method ,and I corresponding InitialState as second arguments

I got a error in browser:

<code>Uncaught Error: Reducer "postsBySubreddit" 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.</code> 

code is here:

import { createStore, applyMiddleware } from 'redux' import thunkMiddleware from 'redux-thunk' import createLogger from 'redux-logger' import rootReducer from '../reducers/reducers' import Immutable from 'immutable' const loggerMiddleware = createLogger() //const initialState=0 function configureStore() {     return createStore(     rootReducer,      {postsBySubreddit:{},selectedSubreddit:'reactjs'},      applyMiddleware(      thunkMiddleware,     loggerMiddleware   )  ) }   export default configureStore 

and I invoked configeStoremethod in Root.js:

 import React, { Component } from 'react'  import { Provider } from 'react-redux'  import configureStore from '../store/configureStore'  import AsyncApp from './AsyncApp'  import Immutable from 'immutable'  const store = configureStore()  console.log(store.getState())  export default class Root extends Component {  render() {    return (      <Provider store={store}>        <AsyncApp />      </Provider>   )  } } 

but I guess this initateState has something wrong:

import { combineReducers } from 'redux' import {reducerCreator} from '../utils/creator' import Immutable from'immutable' import {SELECT_SUBREDDIT, INVALIDATE_SUBREDDIT ,REQUEST_POSTS, RECEIVE_POSTS} from '../actions/action' let initialState=Immutable.fromJS({isFetching: false, didInvalidate: false,items:[]})  function selectedSubreddit(state, action) {   switch (action.type) {   case SELECT_SUBREDDIT:     return action.subreddit   default:     return state   } } function postsBySubreddit(state, action) {   switch (action.type) {     case INVALIDATE_SUBREDDIT:     case RECEIVE_POSTS:     case REQUEST_POSTS:       return Object.assign({}, state, {         [action.subreddit]: posts(state[action.subreddit], action)       })     default:       return state   } } function posts(state=initialState,action) {   switch (action.type) {     case INVALIDATE_SUBREDDIT:       return state.merge({         didInvalidate: true       })     case REQUEST_POSTS:       return state.merge({         isFetching: true,         didInvalidate: false       })     case RECEIVE_POSTS:       return state.merge({         isFetching: false,         didInvalidate: false,         items: action.posts,         lastUpdated: action.receivedAt       })     default:       return state      } }  const rootReducer = combineReducers({   postsBySubreddit,  selectedSubreddit }) export default rootReducer 

but if I set initialState in my every sub reducer it can did word normally. Something wrong?

like image 519
Ice Wilder Avatar asked Apr 14 '16 09:04

Ice Wilder


People also ask

In what condition a reducer can return undefined?

Reducer "blogTypeVisibilityFilter" 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.


1 Answers

The initialState argument in createStore() is often tripping people. It was never meant as a way to “initialize” your application state manually. The only useful applications for it are:

  • Booting up server rendered app from JSON state payload.
  • “Resuming” the app from a state saved into local storage.

It is implied that you never write initialState manually and in most apps you don’t even use it. Instead, reducers must always specify their own initial state, and initialState is just a way to prefill that state when you have an existing serialized version of it.

So this answer is correct: you need to define the initial state in your reducer. Supplying it to createStore() is not enough, and is not meant to be a way to define the initial state in code.

like image 118
Dan Abramov Avatar answered Oct 19 '22 01:10

Dan Abramov