program tip

createStore ()에 initialState를 제공 ​​했음에도 불구하고 "초기화 중에 정의되지 않은 리듀서 […] 반환 됨"이 발생하는 이유는 무엇입니까?

radiobox 2020. 12. 27. 10:33
반응형

createStore ()에 initialState를 제공 ​​했음에도 불구하고 "초기화 중에 정의되지 않은 리듀서 […] 반환 됨"이 발생하는 이유는 무엇입니까?


내 redux createStore 메서드에 InitialState를 설정했으며 InitialState를 두 번째 인수로 대응했습니다.

브라우저에 오류가 있습니다.

<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>

코드는 다음과 같습니다.

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

그리고 다음 configeStore에서 메서드를 호출 했습니다 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>
  )
 }
}

하지만 이것은 initateState뭔가 잘못되었다고 생각합니다 .

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

그러나 initialState모든 하위 감속기를 설정하면 정상적으로 단어를 할 수 있습니다. 뭔가 잘못?


initialState주장 createStore()은 종종 사람들을 걸려 넘어지게합니다. 애플리케이션 상태를 수동으로 "초기화"하는 방법은 아닙니다. 유일하게 유용한 응용 프로그램은 다음과 같습니다.

  • JSON 상태 페이로드에서 서버 렌더링 앱을 부팅합니다.
  • 로컬 저장소에 저장된 상태에서 앱을 "재개"합니다.

initialState수동으로 작성 하지 않으며 대부분의 앱에서 사용하지 않는다는 것을 의미합니다. 대신 리듀서는 항상 자체 초기 상태를 지정 initialState해야하며 기존 직렬화 된 버전이있을 때 해당 상태를 미리 채우는 방법 일뿐입니다.

따라서이 대답 은 맞습니다. 감속기에서 초기 상태를 정의 해야 합니다. 제공하는 것으로 createStore()는 충분하지 않으며 코드에서 초기 상태를 정의하는 방법이 아닙니다.


동일한 오류가 발생했지만 기본 케이스를 포함하지 않았습니다.

function generate(state={} ,action) {
  switch (action.type) {
    case randomNumber:
      return {
        ...state,
        random: action.payload
      }   
    default: // need this for default case
      return state 
   }
}

감속기가 처음 호출되면 상태가 정의되지 않습니다. 그런 다음 초기 상태를 반환해야합니다 (오류 메시지가 알려주는 것입니다). 초기 상태 값을 정의하는 일반적인 방법은 상태 매개 변수의 기본값을 설정하는 것입니다.

function postsBySubreddit(state = {}, action) {}

You have an initial state in the posts function but it is not called during initialization.


Also, make sure that you are returning the default state last in your reducer. Sometimes you can forget to make sure this is the default for your switch statement (when refactoring and moving around code).

...
 default:
  return state

I just hit this same snag because I accidentally redefined state inside my reducer:

const initialState = {
  previous: true,
  later: true
}

const useTypeReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'TOGGLE_USE_TYPES':
      let state = Object.assign({}, state);   // DON'T REDEFINE STATE LIKE THIS!
      state[action.use] = !state[action.use];
      return state;

    default:
      return state;
  }
}

export default useTypeReducer;

To fix the problem I needed to refrain from redefining state:

const initialState = {
  previous: true,
  later: true
}

const useTypeReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'TOGGLE_USE_TYPES':
      let _state = Object.assign({}, state);   // BETTER
      _state[action.use] = !state[action.use];
      return _state;

    default:
      return state;
  }
}

export default useTypeReducer;

tl;dr

Make sure that:

  • You actually pass data to your reducer via the action/action creator!
  • The reducer doesn't return undefined.

Example

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'SET_DATA':
      debugger // Place a breakpoint for investigation
      const result = update(state, {$set: action.data});
      // `result` is `undefined` if `action.data` is too
      return result;
    default:
      return state;
  }
}

In this case, if you accidentally pass undefined to action.data via your action creator then react-addons-update will return the undefined that came from that variable. Since this overwrites the whole reducer state it will return that undefined that will trigger the error.

Debugging

You can debug this by examining these places:

  • Where the reducer creates the new state. Place a breakpoint into that part to make sure you don't receive or return undefined there.
  • Where the data is passed to the action creator.

ReferenceURL : https://stackoverflow.com/questions/36619093/why-do-i-get-reducer-returned-undefined-during-initialization-despite-pr

반응형