J'avais initialisé InitialState dans ma méthode redux createStore, et InitialState correspondant comme second argument
J'ai une erreur dans le navigateur:
<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>
le code est ici:
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
et j'ai invoqué configeStore
method dans 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>
)
}
}
mais je suppose que cette initateState
a quelque chose qui cloche:
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
mais si je mets initialState
dans chacun de mes sous-réducteurs, il peut faire Word normalement. Quelque chose ne va pas?
L'argument initialState
dans createStore()
fait souvent trébucher les gens. Cela n'a jamais été conçu comme un moyen «d'initialiser» votre état d'application manuellement. Les seules applications utiles pour cela sont:
Cela signifie que vous n'écrivez jamais initialState
manuellement et que vous ne l'utilisez même pas dans la plupart des applications. Au lieu de cela, les réducteurs doivent toujours spécifier leur propre état initial, et initialState
est simplement un moyen de pré-remplir cet état lorsque vous en avez une version sérialisée existante.
Donc cette réponse est correcte: vous avez besoin pour définir l’état initial dans votre réducteur. Le fournir à createStore()
n'est pas suffisant et ne constitue pas un moyen de définir l'état initial dans le code.
J'ai eu la même erreur mais je n'ai pas inclus de cas par défaut
function generate(state={} ,action) {
switch (action.type) {
case randomNumber:
return {
...state,
random: action.payload
}
default: // need this for default case
return state
}
}
Lorsque vos réducteurs sont appelés pour la première fois, l'état n'est pas défini. Vous devez ensuite renvoyer l'état initial (c'est ce que vous dit le message d'erreur). La manière habituelle de définir la valeur d'état initiale consiste à définir une valeur par défaut pour le paramètre d'état:
function postsBySubreddit(state = {}, action) {}
Vous avez un état initial dans la fonction posts
mais il n'est pas appelé lors de l'initialisation.
Assurez-vous également que vous avez renvoyé l'état par défaut en dernier dans votre réducteur. Parfois, vous pouvez oublier de vous assurer que c'est la valeur par défaut pour votre instruction switch (lors du refactoring et du déplacement de code).
...
default:
return state
Je viens de toucher le même problème parce que j'ai redéfini accidentellement state
dans mon réducteur:
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;
Pour résoudre le problème, je devais m'abstenir de redéfinir l'état:
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;
Sois sûr que:
undefined
.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;
}
}
Dans ce cas, si vous passez accidentellement undefined
à action.data
via votre créateur d'action, alors react-addons-update renverra la undefined
provenant de cette variable. Etant donné que ceci écrase tout l’état du réducteur, la variable undefined
qui déclenchera l’erreur sera renvoyée.
Vous pouvez résoudre ce problème en examinant ces endroits:
undefined
.