React-Redux:组合reducer:意外密钥

ste*_*eel 49 reactjs redux redux-thunk

在我开始组合我的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
})
Run Code Online (Sandbox Code Playgroud)

这会导致功能损坏和控制台错误:

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]
)
Run Code Online (Sandbox Code Playgroud)

我怎样才能正确组合减速器?

nra*_*itz 63

我认为您只需要为附加键添加Reducer,例如

function one(state = {}, action) {
  switch (action.type) {
  case ONE_UPDATED:
    return action.one
  default:
    return state
  }
}
Run Code Online (Sandbox Code Playgroud)

来自文档:

如果使用combineReducers生成reducer,则它必须是一个普通对象,其形状与传递给它的键相同.否则,您可以自由地传递减速器可以理解的任何内容.

如果您不需要处理与oneor 相关的任何操作two,只需将它们拉入最初,这可能就像这样简单

export default combineReducers({
  events,
  flash,
  one: (state = {}) => state,
  two: (state = {}) => state
})
Run Code Online (Sandbox Code Playgroud)


tot*_*dli 9

TL;博士

如果你做SSR,重新编译你的服务器端捆绑!

说明

当您执行服务器端呈现(SSR)时,会出现此错误消息,更改 reducer代码中的某些内容,并且您在客户端重新编译/ HMR.

当您执行SSR时,必须将Redux存储序列化为全局变量(如window.__INITIAL_STATE__),因此在初始化客户端时,createStore可以读取它并构建相同的Redux状态.

如果不重新编译服务器端的修改代码,则服务器的初始状态可能仍包含具有旧密钥的状态(来自旧的reducer),而客户端具有新状态(来自新的/修改的reducer) ).

从技术上讲,这不会破坏客户端的工作方式,因为Redux会忽略意外的密钥,它只是一个有用的警告(实际上是一个错误),它会记住你重新编译服务器端软件包.因此,这可能是生产中的一个问题,或者当您对水合性能进行基准测试时,因为不同的状态会导致不同的DOM.当然,这种错误不应该在生产中发生,因为您的部署过程应该自动创建客户端和服务器端捆绑.