I am getting the error Unexpected key "characters" found in initialState argument passed to createStore. Expected to find one of the known reducer keys instead: "marvelReducer", "routing". Unexpected keys will be ignored.
rootReducer :
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import marvelReducer from './marvelReducer';
const rootReducer = combineReducers({
marvelReducer,
routing: routerReducer
});
export default rootReducer;
marvelReducer :
import { FETCH_MARVEL } from '../constants/constants';
import objectAssign from 'object-assign';
export default function marvelReducer(state = [], action) {
switch (action.type) {
case FETCH_MARVEL:
return objectAssign({}, state, {characters: action.data});
default:
return state;
}
}
store :
import { createStore } from 'redux';
import { syncHistoryWithStore } from 'react-router-redux';
import { browserHistory } from 'react-router';
import rootReducer from '../reducers/index';
const initialState = {
characters: []
};
const store = createStore(rootReducer, initialState);
export const history = syncHistoryWithStore(browserHistory, store);
if (module.hot) {
module.hot.accept('../reducers/', () => {
const nextRootReducer = require('../reducers/index').default;
store.replaceReducer(nextRootReducer);
});
}
export default store;
I have very similar code in another application and it's working fine. Not sure what's going on here
There's a small mismatch between what you set as the initial state of the store and what you tell the store to expect what the initial state of the store should be, e.g. - update your initial state setting for the store as such:
const initialState = {
marvel: {
characters: []
}
};
And also it's a good idea to name your state tree variable holders to meaningful names that do not contain reducer in them, so update
const rootReducer = combineReducers({
marvelReducer,
routing: routerReducer
});
to
const rootReducer = combineReducers({
marvel: marvelReducer,
routing: routerReducer
});
And that should do the trick for you.
Hope this helps,
PS. some docs.
From the docs:
If you produced reducer with combineReducers, this must be a plain object with the same shape as the keys passed to it. Otherwise, you are free to pass anything that your reducer can understand.
If you don't need to handle any actions related to one
or two
, just pull them in initially, this could be as simple as
export default combineReducers({
events,
flash,
one: (state = {}) => state,
two: (state = {}) => state
})
From the documentation for combineReducers
:
The
combineReducers
helper function turns an object whose values are different reducing functions into a single reducing function you can pass tocreateStore
.The resulting reducer calls every child reducer, and gathers their results into a single state object. The shape of the state object matches the keys of the passed
reducers
.
In short, your reducers are configured to handle a state in the form of
{
marvelReducer,
routing
}
But you are handing it an initial state in the form of
{
characters
}
To fix this issue, you will either have to change the keys of the object you pass to combineReducers
to include characters
, or change the initial state to contain the keys that your reducers are expecting.
To add to elod answer, The store state object has different properties or different data sections:
{a:data,b:data,c:data}
When you combine reducers, you MUST map each property of the state object to a different reducer
{a:reducerOfDataA,b:reducerOfDataB,c:reducerOfDataC}
This is a mechanism in redux which enforces seperation of data concern for each reducer, reducerOfDataA cannot modify data of reducerOfDataB . This means that all data of reducerOfDataA must sit under {a:...} and not be divided under different properties directly on the root state object {partA1:... , partA2 :...}
Took me entire night to figure this out, hope this little comment will save yours.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With