type tutorial react actions javascript redux react-redux

javascript - tutorial - ¿Por qué obtengo "Reducer[...] devuelto indefinido durante la inicialización" a pesar de proporcionar initialState a createStore()?



redux-thunk (5)

Acabo de golpear esta misma pega porque accidentalmente redefiní el state dentro de mi reductor:

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;

Para solucionar el problema, necesitaba abstenerme de redefinir el estado:

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;

Había establecido InitialState en mi método redux createStore, y correspondiendo InitialState como segundos argumentos

Recibí un error en el navegador:

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

el código está aquí:

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

e configeStore método Root.js en 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> ) } }

pero supongo que este initateState tiene algo mal:

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

pero si configuro initialState en cada uno de mis sub-reductores, puedo hacerlo normalmente. ¿Algo mal?


Además, asegúrese de devolver el estado predeterminado al último en su reductor. A veces puede olvidarse de asegurarse de que este es el valor predeterminado para su declaración de cambio (al refactorizar y moverse por el código).

... default: return state


Cuando se invocan sus reductores por primera vez, el estado no está definido. A continuación, debe devolver el estado inicial (eso es lo que el mensaje de error le está diciendo). La forma habitual de definir el valor de estado inicial es establecer un valor predeterminado para el parámetro de estado:

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

Tiene un estado inicial en la función de posts pero no se llama durante la inicialización.


El argumento initialState en createStore() menudo está tropezando gente. Nunca fue una forma de "inicializar" el estado de su aplicación manualmente. Las únicas aplicaciones útiles para esto son:

  • Arrancando la aplicación del servidor desde la carga útil del estado JSON.
  • "Reanudar" la aplicación desde un estado guardado en el almacenamiento local.

Está implícito que nunca se escribe initialState manualmente y en la mayoría de las aplicaciones ni siquiera se usa. En cambio, los reductores siempre deben especificar su propio estado inicial, e initialState es solo una manera de rellenar ese estado cuando tienes una versión serializada existente de él.

Entonces esta respuesta es correcta: necesitas definir el estado inicial en tu reductor. Suministrarlo a createStore() no es suficiente, y no pretende ser una forma de definir el estado inicial en el código.


Tuve el mismo error pero no incluí un caso predeterminado

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