web-dev-qa-db-ja.com

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

これにより、機能が破損し、コンソールエラーが発生します。

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

減速機を正しく組み合わせるにはどうすればよいですか?

46
steel

追加のキーにレデューサーを追加するだけでいいと思います。

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

ドキュメント から:

ComposeReducersでリデューサーを作成した場合、これは渡されるキーと同じ形状のプレーンオブジェクトでなければなりません。それ以外の場合、レデューサーが理解できるものなら何でも自由に渡すことができます。

oneまたはtwoに関連するアクションを処理する必要がない場合は、最初にそれらを取得するだけで、これは次のように簡単になります。

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

tl; dr

SSRを実行する場合は、サーバー側のバンドルを再コンパイルしてください!

説明

このエラーメッセージは、サーバーサイドレンダリング(SSR)を実行し、レデューサーのコードで何かを変更すると表示される可能性がありますおよびonly recompile /クライアント側でHMR it

SSRを実行する場合、Reduxストアをグローバル変数(window.__INITIAL_STATE__など)にシリアル化する必要があるため、クライアント側を初期化するときに createStore が読み取れ、同じRedux状態を構築します。

サーバー側の変更されたコードを再コンパイルしない場合、サーバーからの初期状態には、クライアント側が古いキー(古いレデューサーから)の状態がまだ含まれている可能性があります(新しい/変更されたレデューサーから)新しい状態になります。

技術的には、クライアント側の動作を中断することはありません。Reduxは予期しないキーを無視するためです。これは、サーバー側のバンドルを再コンパイルすることを思い出させる便利な警告(実際にはエラーではありません)です。トー、これは本番環境またはベンチマーク ハイドレーション パフォーマンスの問題になる可能性があります。これは、状態が異なるとDOMが異なる可能性があるためです。もちろん、展開プロセスでクライアント側とサーバー側の両方のバンドルが自動的に作成されるため、この間違いは本番環境では発生しません。

9
totymedli