Ich hatte InitialState in meiner redux createStore-Methode festgelegt und InitialState als zweites Argument angegeben
Ich habe eine Fehlermeldung im Browser erhalten:
<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 ist hier:
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
und ich habe die configeStore
Methode aufgerufen 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>
)
}
}
aber ich denke das initateState
hat etwas falsches:
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
aber wenn ich initialState
in jedem Sub-Reduzierer setze , kann es normal sprechen. Etwas stimmt nicht?
quelle
All reducers are passed undefined on initialization, so they should be written such that when given undefined
Ich hatte den gleichen Fehler, aber keinen Standardfall angegeben
function generate(state={} ,action) { switch (action.type) { case randomNumber: return { ...state, random: action.payload } default: // need this for default case return state } }
quelle
Stellen Sie außerdem sicher, dass Sie den Standardstatus zuletzt in Ihrem Reduzierer zurückgeben. Manchmal können Sie vergessen, sicherzustellen, dass dies die Standardeinstellung für Ihre switch-Anweisung ist (beim Umgestalten und Bewegen von Code).
... default: return state
quelle
Wenn Ihre Reduzierungen zum ersten Mal aufgerufen werden, ist der Status undefiniert. Sie müssen dann den Ausgangszustand zurückgeben (das sagt Ihnen die Fehlermeldung). Die übliche Methode zum Definieren des Anfangszustandswerts besteht darin, einen Standardwert für den Zustandsparameter festzulegen:
function postsBySubreddit(state = {}, action) {}
Sie haben einen Anfangszustand in der
posts
Funktion, der jedoch während der Initialisierung nicht aufgerufen wird.quelle
Ich habe gerade den gleichen Haken getroffen, weil ich versehentlich
state
in meinem Reduzierer neu definiert habe: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;
Um das Problem zu beheben, musste ich den Zustand nicht neu definieren:
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;
quelle
gemäß der Dokumentation von Redux: https://redux.js.org/basics/reducers
Sie müssen den Status außerhalb der Schalterfunktion wie folgt zurückgeben:
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 } //here you should put the return state return state }
quelle
tl; dr
Stelle sicher das:
undefined
.Beispiel
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 diesem Fall , wenn Sie versehentlich passieren
undefined
zuaction.data
über Ihre Aktion Schöpfer dann reagieren-addons-Update wird die Rückkehr ,undefined
die von diesen Variablen kam. Da dies den gesamten Reduziererstatus überschreibt, wird dies zurückgegebenundefined
dass dies den Fehler auslöst.Debuggen
Sie können dies debuggen, indem Sie die folgenden Stellen untersuchen:
undefined
.quelle