React-Redux: объединение редукторов: неожиданные ключи

мое приложение отлично работает, прежде чем я начну объединять свои редукторы 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
})

это приводит к нарушенной функциональности и консоль of:

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]
)

Как правильно комбинировать редукторы?

2 ответов


Я думаю, вам просто нужно добавить редукторы для дополнительных ключей, например

function one(state = {}, action) {
  switch (action.type) {
  case ONE_UPDATED:
    return action.one
  default:
    return state
  }
}

С документы:

если вы произвели редуктор с combineReducers, то это должно быть простым объектом с такой же формой как ключи переданные к нему. В противном случае вы можете передать все, что может понять ваш редуктор.

Если вам не нужно обрабатывать любые действия, связанные с one или two, просто вытащите их изначально, это может быть так же просто, как

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

tl; dr

если вы делаете SSR, перекомпилируйте пакет на стороне сервера!

объяснение

это сообщение об ошибке может появиться, когда вы делаете рендеринга на стороне сервера (SSR), изменить что-то в коде редуктора и только перекомпилировать / HMR на стороне клиента.

когда вы делаете SSR, вы должны сериализовать свой магазин Redux в глобальную переменную (например,window.__INITIAL_STATE__), поэтому при инициализации клиентской стороны, createStore может прочитать это и построить то же состояние Redux.

если вы не перекомпилируете измененный код на стороне сервера, начальное состояние сервера может по-прежнему содержать состояние со старыми ключами (из старых редукторов), в то время как клиентская сторона имеет новое состояние (из новых/модифицированных редукторов).

технически это не сломает, как работает клиентская сторона, потому что Redux игнорирует неожиданные ключи, это просто полезное предупреждение (не совсем ошибка), который помнит, что вы перекомпилировали пакет на стороне сервера. Хотя, это может быть проблемой в производстве или при тест увлажнение производительность, потому что другое состояние может привести к другому DOM. Конечно, эта ошибка не должна произойти в производстве, потому что процесс развертывания должен автоматически создавать как клиентский, так и серверный пакет.