「.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
create-react-appを使用した、React + Reduxの step by step。
手順1 †
色々悩んだが(と言うか、コレのRedux化に失敗したため)、
先ずは、以下の「Example: Todo List」のClass化版をやることに。
ココでは、Web備忘録の方をやってみた。
構成 †
─ src/
├─ App.js
├─ index.js
├┬ actions/
│└─ Todo.js
├┬ components/
│└─ Todo.js
├┬ containers/
│└─ Todo.js
├┬ reducers/
│└─ Todo.js
└── createStore.js
サンプルの生成 †
>create-react-app react-redux-todo
インストール †
>npm install --save redux react-redux redux-logger
デバッグ設定 †
デバッグ設定を行っておく。
実装 †
以下を見ても明らかだが、
Entry Point, Component, Action, Reducer
と、複数のモジュールを行き来してシンドい。
Store作成 †
- ポイント
- combineReducersをココで書いている。
- applyMiddlewareで、
Reduxの状態遷移をコンソール上に表示する
redux-logger ミドルウェアを追加する。
Reducer作成(仮) †
- reducers/Todo.jsを作成する。
前述のStoreでimportしているReducerを仮で作成。
- index.jsに組込む。
- createStoreして、storeを生成する。
- AppタグをProviderタグでラップしつつstore属性にstoreを設定。
- ここで一度 npm start コマンドを実行し動作することを確認。
Component作成 †
- components/Todo.jsを作成する。
- そして、App.jsを修正してTodoを呼び出す。
Action作成 †
Reducer修正 †
- Reducer(仮)のreducers/Todo.jsにActionに対応した処理を実装する。
- Actionから渡された値を「処理して」Componentに渡す。の処理の部分。
- ポイント
- 初期値はinitialStateで定義して使用する。
- state は書き換えるのではなく新たなオブジェクトとするので、
Object.assignでディープコピーし、それに値を設定し、戻り値とする。
Container作成 †
- containers/Todo.jsを作成する。
- そして、App.jsを修正してTodoをComponentからContainerに切り替える。
Component修正 †
- components/Todo.jsで、propsのstateとfunctionを参照するように変更する。
実行 †
- デバッグ実行すると、redux-logger ミドルウェアで、
Reduxの状態遷移はコンソール上に表示される。
サンプル †
https://github.com/OpenTouryoProject/SampleProgram/tree/master/Template/SPATemplate/react-redux-todo
手順2 †
「Example: Todo List」が動作したので、先程失敗したコチラのRedux化に再チャレンジ。
プロジェクトの準備 †
インストール †
>npm install --save redux react-redux redux-logger
デバッグ設定 †
デバッグ設定を行っておく。
Component毎 †
実装 †
以下の辺りに注意しながら実装する。
- redux-loggerを使用
- createStoreの定義
- Actionの分割
- Reducerの書き方
- Containerの使用
- Componentからの参照方法
実行 †
- redux-loggerで、Reducersが動いていることは確認できるが、
Component側が更新されない(State -> Componentの再実行がかかってない)。
考えて設計して欲しい感がある。
参考 †
Componentを跨ぐ †
Componentを跨ぐという初歩的なことも良く解らないので、
ネットを調べて以下の参考ページを発見したのでやってみる。
実装 †
Menu1、Menu2のContainerを集約するContainer, Action, Reducerを、Menu12に集約。
- Containerネストは不可能なので、Containerを集約する。
- 従ってContainer以外にも、 Action, Reducerの集約を行う。
- 親Containerから子Componentへは、propsを使用してstateとfunctionを渡す。
実行 †
無事、動作!
参考 †
サンプル †
https://github.com/OpenTouryoProject/SampleProgram/tree/master/Template/SPATemplate/redux_app
手順3 †
- コチラのRedux化
- コチラの下記の新しい要素も追加する。
- ページング処理
- Hot Reloading
- redux-thunkによる非同期処理
プロジェクトの準備 †
デバッグ設定 †
デバッグ設定を行っておく。
インストール †
実装 †
- 手順1の手順を参考に、本丸のRedux化に取り掛かる。
- Counter、FetchData?の順にモジュールを追加していくと良い。
Store作成 †
- ポイント
- combineReducersをココで書いている。
- applyMiddlewareで、
- Reduxの状態遷移をコンソール上に表示する redux-logger ミドルウェアを追加する。
- 非同期処理を行うための thunk ミドルウェアを追加する。
Reducer作成(仮) †
- 仮のReducerを作成
- Counter、FetchData?の順にモジュールを追加
- また、routes.jsにページング処理のためのBrowserRouter?を組込む。
- BrowserRouter?のインポート
import { BrowserRouter as Router, Route } from 'react-router-dom'
- LayoutタグをBrowserRouter?のタグで囲む(なお、?はnull許容のもよう)
<Router>
<Layout>
・・・
<Route path='/fetchdata/:startDateIndex?' component={ FetchData } />
</Layout>
</Router>
- ここで一度 npm start コマンドを実行し動作することを確認。
Component作成 †
作成済みなのでココでは何もしない。
Action作成 †
- Actionを作成
- Counter、FetchData?の順にモジュールを追加
- ポイント
- Counterは通常通り。
- FetchData?は
- 非同期処理自体をReducerではなくココに定義。
- 非同期処理の結果として、通常のActionを呼び出す。
Reducer修正 †
- Reducer(仮)のreducers/Counter、FetchData?.jsにActionに対応した処理を実装する。
- Actionから渡された値を「処理して」Componentに渡す。の処理の部分。
- ポイント
- 初期値はinitialStateで定義して使用する。
- state は書き換えるのではなく新たなオブジェクトとするので、
Object.assignでディープコピーし、それに値を設定し、戻り値とする。
Container作成 †
- containers/Counter、FetchData?.jsを作成する。
- そして、routes.jsを修正してCounter、FetchData?をComponentからContainerに切り替える。
- ポイント:ここでconnectする。
- Counterは通常通り。
- FetchData?はActionに定義した非同期処理を呼び出す。
Component修正 †
- components/Counter、FetchData?.jsで、propsのstateとfunctionを参照するように変更する。
- なお、componentWillReceiveProps?は無限ループ(stack overflow)防止コードが必要だった。
実行 †
無事、動作!
サンプル †
参考 †
- redux-thunkによる非同期処理
注意:react-reduxを使っているか?いないか?で、サンプル・コードが大きく異なる。
参考 †