在我开始组合我的Redux减速器之前,我的应用程序正常工作。但是当我合并时,initialState和reducer键会混淆。
function flash(state = [], action) {
switch (action.type) {
case FLASH_MESSAGE_UPDATED:
return _.extend({}, state, { flash: action.flash })
default:
return state
}
}
function events(state = [], action) {
switch (action.type) {
case EVENTS_UPDATED:
return _.extend({}, state, { events: action.pathway_events })
default:
return state
}
}
export default combineReducers({
events,
flash
})
这导致功能损坏和控制台错误:
Unexpected keys "one", "two" found in initialState argument passed to createStore. Expected to find one of the known reducer keys instead: "events", "flash". Unexpected keys will be ignored.
我的初始状态是在redux-thunk的帮助下传递的。
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from '../../reducers/event'
let initialState = {
one: globalData.one,
two: globalData.two,
events: globalData.events,
flash: globalData.flash
}
let createStoreWithMiddleware = applyMiddleware(thunk)(createStore)
let reduxStore = createStoreWithMiddleware(reducer, initialState);
React.render(
<Provider store={reduxStore}>
<EventListContainer />
</Provider>,
$('.events')[0]
)
如何正确组合减速器?
答案 0 :(得分:57)
我认为你只需要为附加键添加reducer,例如
function one(state = {}, action) {
switch (action.type) {
case ONE_UPDATED:
return action.one
default:
return state
}
}
来自the docs:
如果使用combineReducers生成reducer,则它必须是一个普通对象,其形状与传递给它的键相同。否则,您可以自由地传递减速器可以理解的任何内容。
如果您不需要处理与one
或two
相关的任何操作,请先将它们拉进去,这可能就像
export default combineReducers({
events,
flash,
one: (state = {}) => state,
two: (state = {}) => state
})
答案 1 :(得分:8)
如果您执行SSR,请重新编译服务器端捆绑包!
当您在reducer的代码中执行服务器端呈现(SSR),更改并且仅重新编译/时,可能会出现此错误消息HMR在客户端。
当您执行SSR时,您必须将Redux存储序列化为全局变量(如window.__INITIAL_STATE__
),因此在初始化客户端时,createStore
可以读取它并构建相同的Redux状态
如果您不为服务器端重新编译修改后的代码,则服务器的初始状态可能仍包含具有旧密钥的状态(来自旧的reducer),而客户端side有新状态(来自new / modified reducers)。
从技术上讲,这不会打破客户端如何工作,因为Redux忽略了意外的密钥,它只是一个有用的警告(实际上是一个错误),它记得你重新编译你的服务器端软件包。因此,这可能是生产中的一个问题,或者当您对hydration性能进行基准测试时,因为不同的状态可能会导致不同的DOM。当然,这个错误不应该在生产中发生,因为您的部署过程应该自动创建客户端和服务器端捆绑。