はじめに
WebpackとReact Hot Loaderを使うことでReactコンポーネントのHot Reloadingができるが、Reduxを使った場合にreducerのHot Reloadingにはコツが必要だったので書いておく。また、TypeScriptを使って書く場合には追加で注意事項もあるので合わせて書いておく。
前提
React Hot Loaderは現在v3系が開発中だが、今回は2016/06/20時点で安定版の v1.3.0 で動作確認している。動作確認はしていないが、v3系でも同様の方法でいけるはず。
方法
ReduxのcreateStore
を呼んでStoreを作成している箇所に、Hot Reloading用のコードを入れる必要がある。
import { createStore } from 'redux';
import rootReducer from '../reducers';
export default function configureStore(initialState) {
return createStore(rootReducer, initialState);
}
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState, enhancer);
if (module.hot) {
module.hot.accept('../reducers', () =>
store.replaceReducer(require('../reducers').default)
);
}
return store;
}
※reducerモジュールのパス ../reducers
は適宜アプリケーション構成に合わせて修正すること
TypeScriptで書く場合の注意点
自分はTypeScriptで書いていて見事にハマったので書いておく。
何も考えずにmodule.hot
と書くとTypeScriptがエラーを吐いてしまうので、最初以下の様に書いて回避していたのだが、これだとHot Reloadingが動作せず困っていた。
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState, enhancer);
if (module['hot']) {
module['hot'].accept('../reducers', () =>
store.replaceReducer(require('../reducers').default)
);
}
return store;
}
Hot Reloadingのコードをデバッグしてみたところ、accept
で渡される引数が../reducers
のままで渡っていた。JavaScriptで動作する環境で確認すると、ここはモジュール名ではなく数値のモジュールIDが渡ってきていた。
ここでmodule.hot.accept
でないとWebpackがうまく変換できないのだろう、と推測。
というわけで、下記のように一旦declare var module: any
を宣言してmodule.hot.accept
と書けるように変更したところ、無事に動作するようになった。
declare var module: any;
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState, enhancer);
if (module.hot) {
module.hot.accept('../reducers', () =>
store.replaceReducer(require('../reducers').default)
);
}
return store;
}
というわけで、module.hot.accept
と書かなければならないので注意しよう。
参考
redux reducer hot reloading などでググると以下のIssueコメントにたどりついた。ここで作者のDanさんがreducerのHot Reloading方法について説明していた。
Starter Kits
React Hot Loader で紹介されているStarter Kits 一覧 には、ReduxでHot Reloadingを組み込んだものとして2つ紹介されている。ともに下記の箇所でReducerのHot Reloadingにも対応するためのコードが入れられている。これらのStarter Kitsを使っておけば大丈夫。