Javascript React Redux传递到创建存储的意外密钥

Javascript React Redux传递到创建存储的意外密钥,javascript,reactjs,redux,Javascript,Reactjs,Redux,我在传递给createStore的initialState参数中发现错误意外键“characters”。期望找到一个已知的reducer键:“marvelReducer”、“routing”。意外的键将被忽略。 减根剂: import { combineReducers } from 'redux'; import { routerReducer } from 'react-router-redux'; import marvelReducer from './marvelReducer'

我在传递给createStore的initialState参数中发现错误
意外键“characters”。期望找到一个已知的reducer键:“marvelReducer”、“routing”。意外的键将被忽略。

减根剂:

 import { combineReducers } from 'redux';
 import { routerReducer } from 'react-router-redux';
 import marvelReducer from './marvelReducer';

 const rootReducer = combineReducers({
   marvelReducer,
   routing: routerReducer
 });
 export default rootReducer;
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;
  }
}
惊奇减速机:

 import { combineReducers } from 'redux';
 import { routerReducer } from 'react-router-redux';
 import marvelReducer from './marvelReducer';

 const rootReducer = combineReducers({
   marvelReducer,
   routing: routerReducer
 });
 export default rootReducer;
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;
  }
}
商店:

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;
我在另一个应用程序中有非常相似的代码,它运行良好。不确定此处发生了什么

来自for
组合传感器

combineReducers
helper函数用于转换值为 可以将不同的缩减函数合并为单个缩减函数 传递到
createStore

生成的reducer调用每个子reducer,并收集它们的 将结果转换为单个状态对象状态对象的形状 匹配传递的
减速器的键

简言之,您的减速器配置为处理以下形式的状态:

{
    marvelReducer,
    routing
}
{
    characters
}
但你是以

{
    marvelReducer,
    routing
}
{
    characters
}

要解决此问题,您必须更改传递给
组合转换器的对象的键,以包含
字符
,或者更改初始状态以包含还原程序所期望的键。

在设置为存储的初始状态和告诉存储期望存储的初始状态之间存在小的不匹配,例如,更新存储的初始状态设置:

const initialState = {
   marvel: {
     characters: []
   }
};
另外,最好将状态树变量持有者命名为不包含reducer的有意义的名称,以便更新

const rootReducer = combineReducers({
   marvelReducer,
   routing: routerReducer
});

这应该对你有好处

希望这有帮助

附:一些文件

发件人:

如果使用组合减速器生成减速器,则该对象必须是与传递给它的关键帧具有相同形状的普通对象。否则,你可以自由地传递任何你能理解的东西

如果您不需要处理与
one
two
相关的任何操作,只需在开始时将它们拉入即可,这可能非常简单

export default combineReducers({
  events,
  flash,
  one: (state = {}) => state,
  two: (state = {}) => state
})

我也有同样的问题,我无法遵循这些潜在解决方案的逻辑

CombineReducer的参数是对reducer对象的引用,而不是对状态键的引用。关键错误与大多数其他redux错误一样神秘,事实上,大多数答案或提供给他们的潜在解决方案也是如此。

要添加到elod答案中, 存储状态对象具有不同的属性或不同的数据部分:

{a:data,b:data,c:data}
组合减速器时,必须将状态对象的每个属性映射到不同的减速器

{a:reducerOfDataA,b:reducerOfDataB,c:reducerOfDataC}
这是redux中的一种机制,它强制每个reducer的数据关注点分离,reducerOfDataA不能修改reducerOfDataB的数据。 这意味着reducerOfDataA的所有数据必须位于{a:…}下,并且不能直接在根状态对象{partA1:…,partA2:…}上的不同属性下进行划分


我花了整整一个晚上才弄明白这一点,希望这个小评论能帮你省下时间。

将初始状态设置为与减速器相同的属性名称,这会覆盖减速器吗?@erichardson30不会-它只会设置初始状态,不会覆盖减速器。下面是来自
[initialState](任意)的更多指导:初始状态。您可以选择将其指定为在universal apps中从服务器恢复状态,或恢复以前序列化的用户会话。如果使用组合减速器生成减速器,则该对象必须是与传递给它的关键帧具有相同形状的普通对象。否则,您可以自由地传递减速机可以理解的任何内容。
“您设置为存储初始状态的内容与您告诉存储期望存储初始状态的内容之间有一点不匹配”我真的无法理解这句话,你能说得更清楚一点吗?你能把你的状态描述出来吗?答案试图解释的是,如果您有一个看起来像
const rootReducer=combineReducers({marvel:marvelReducer,routing:routerReducer})的根还原程序
那么您的状态应该包含一个marvel对象和一个routing对象,其中包含所有属性