- 追加された行はこの色です。
- 削除された行はこの色です。
「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。
-戻る
--[[React]] -> [[Redux]]
--[[Reactのファースト・ステップ]]
*目次 [#a4c3ea2d]
#contents
*概要 [#c8d6c3ab]
create-react-appを使用した、[[React]] + [[Redux]]の step by step。
*手順1 [#fa5b6488]
色々悩んだが(と言うか、[[コレ>Reactのファースト・ステップ#n908d0bb]]の[[Redux]]化に失敗したため)、~
先ずは、以下の「Example: Todo List」のClass化版をやることに。
-React+Redux で Todoアプリを作ってみる │ Web備忘録~
https://webbibouroku.com/Blog/Article/react-redux-todo
-React Redux勝手にチュートリアル(TODO List) - TOEIC940点の文系プログラマー~
http://uraway.hatenablog.com/entry/2016/02/12/182048
ココでは、Web備忘録の方をやってみた。
**構成 [#s527e278]
─ src/
├─ App.js
├─ index.js
├┬ actions/
│└─ Todo.js
├┬ components/
│└─ Todo.js
├┬ containers/
│└─ Todo.js
├┬ reducers/
│└─ Todo.js
└── createStore.js
**サンプルの生成 [#j3dbf15d]
>create-react-app react-redux-todo
**インストール [#maeb5c00]
>npm install --save redux react-redux redux-logger
**デバッグ設定 [#da9433e7]
[[デバッグ設定>Reactのファースト・ステップ#v9b02d5b]]を行っておく。
**実装 [#idc1c700]
以下を見ても明らかだが、
>Entry Point, Component, Action, Reducer
と、複数のモジュールを行き来してシンドい。
***Store作成 [#ca8d8207]
-createStore.jsを作成する。
-ポイント
--combineReducersをココで書いている。
--applyMiddlewareで、~
Reduxの状態遷移をコンソール上に表示する~
redux-logger ミドルウェアを追加する。
***Reducer作成(仮) [#h687216a]
-reducers/Todo.jsを作成する。~
[[前述のStore>#ca8d8207]]でimportしているReducerを仮で作成。
***[[Redux]]の組込 [#b10d5297]
-index.jsに組込む。
--createStoreして、storeを生成する。
--AppタグをProviderタグでラップしつつstore属性にstoreを設定。
-ここで一度 npm start コマンドを実行し動作することを確認。
***Component作成 [#ba4ac550]
-components/Todo.jsを作成する。
-そして、App.jsを修正してTodoを呼び出す。
***Action作成 [#v89cb346]
-actions/Todo.jsを作成する。
***Reducer修正 [#fd58d1c4]
-Reducer(仮)のreducers/Todo.jsにActionに対応した処理を実装する。
-Actionから渡された値を「処理して」Componentに渡す。の処理の部分。
-ポイント
--初期値はinitialStateで定義して使用する。
--state は書き換えるのではなく新たなオブジェクトとするので、~
Object.assignでディープコピーし、それに値を設定し、戻り値とする。
--
***Container作成 [#r8f048de]
-containers/Todo.jsを作成する。
-そして、App.jsを修正してTodoをComponentからContainerに切り替える。
-ポイント:ここでconnectする。
***Component修正 [#mcd78a14]
-components/Todo.jsで、propsのstateとfunctionを参照するように変更する。
**実行 [#sfd06e8d]
-Todoアプリを実行して動作確認する。
-[[デバッグ実行>Reactのファースト・ステップ#v9b02d5b]]すると、redux-logger ミドルウェアで、~
[[Redux]]の状態遷移はコンソール上に表示される。
**サンプル [#z14db030]
https://github.com/OpenTouryoProject/SampleProgram/tree/master/Template/SPATemplate/react-redux-todo
*手順2 [#m993fb4d]
「Example: Todo List」が動作したので、[[先程>#fa5b6488]]失敗した[[コチラ>Reactのファースト・ステップ#n908d0bb]]の[[Redux]]化に再チャレンジ。
**プロジェクトの準備 [#c9c35b8c]
-[[コチラ>Reactのファースト・ステップ#n908d0bb]]をコピーしてredux_appにリネーム。
-必要に応じて[[npmのインストール・コマンド>npm#ta17153d]]で~
node_modulesを復元する必要がある。
npm i
**インストール [#t42a87de]
>npm install --save redux react-redux redux-logger
**デバッグ設定 [#ae168770]
[[デバッグ設定>Reactのファースト・ステップ#v9b02d5b]]を行っておく。
**Component毎 [#tef34d40]
***実装 [#haacb1a8]
以下の辺りに注意しながら実装する。
-redux-loggerを使用
-createStoreの定義
-Actionの分割
-Reducerの書き方
-Containerの使用
-Componentからの参照方法
***実行 [#bbb13e6f]
-またも動かない。
-redux-loggerで、Reducersが動いていることは確認できるが、~
Component側が更新されない(State -> Componentの再実行がかかってない)。
-散々調べた挙げ句、原因は下で、
--combineReducersを使うと以下のようにStoreが階層化されるため、
{"Menu1":{"counter":0},"Menu2":{"counter":0}}
--mapDispatchToPropsで、コレを考慮した設定にする必要があった。
const mapStateToProps = state => {
return {
counter: state.Menu1.counter
}
}
-[[Redux]]さん、もっと、
--使い易さと、
--デバッグし易さを、
>考えて設計して欲しい感がある。
***参考 [#tffeb8df]
-combineReducersでハマったメモ~
https://qiita.com/usagi-f/items/ae568fb64c2eac882d05
-react-reduxで「dispatch is not a function」にハマった場合の対処法~
https://qiita.com/gaku3601/items/f77523bca6661f72f46a
**Componentを跨ぐ [#gb1bc625]
Componentを跨ぐという初歩的なことも良く解らないので、~
ネットを調べて以下の[[参考ページ>#t16b734d]]を発見したのでやってみる。
***実装 [#h67e8391]
Menu1、Menu2のContainerを集約するContainer, Action, Reducerを、Menu12に集約。
-Containerネストは不可能なので、Containerを集約する。
-従ってContainer以外にも、 Action, Reducerの集約を行う。
-親Containerから子Componentへは、propsを使用してstateとfunctionを渡す。
***実行 [#xf51363b]
無事、動作!
***参考 [#t16b734d]
-Stack Overflow
--javascript - React & Redux : connect() to multiple components & best practices~
https://stackoverflow.com/questions/35032204/react-redux-connect-to-multiple-components-best-practices
--reactjs - React Redux: More containers v.s. less containers~
https://stackoverflow.com/questions/39377712/react-redux-more-containers-v-s-less-containers
-Qiita
--何をreduxのコンテナにするか~
https://qiita.com/halhide/items/b9c80b69630ac89b8797
**サンプル [#t7bf1183]
https://github.com/OpenTouryoProject/SampleProgram/tree/master/Template/SPATemplate/redux_app
*手順3 [#s4a24c70]
-[[コチラ>Reactのファースト・ステップ#gf8301c9]]の[[Redux]]化
-[[コチラ>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Core%20React%2BRedux%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88]]の下記の新しい要素も追加する。
--ページング処理
--Hot Reloading
--redux-thunkによる非同期処理
**プロジェクトの準備 [#f5f18271]
-[[コチラ>Reactのファースト・ステップ#gf8301c9]]をコピーしてredux_templateにリネーム。
-必要に応じて[[npmのインストール・コマンド>npm#ta17153d]]で~
node_modulesを復元する必要がある。
npm i
**デバッグ設定 [#t88ebb02]
[[デバッグ設定>Reactのファースト・ステップ#v9b02d5b]]を行っておく。
**インストール [#maeb5c00]
-既知のモジュール
>npm install --save redux react-redux redux-logger
-[[コチラ>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Core%20React%2BRedux%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88]]の新しいモジュール
>npm install --save redux-thunk react-router-redux node-noop history domain-task
**実装 [#p848397e]
-手順1の手順を参考に、本丸の[[Redux]]化に取り掛かる。
-Counter、FetchDataの順にモジュールを追加していくと良い。
--StoreのHot Reloadingが今のところ不明。
***Store作成 [#sdb092fa]
-createStore.jsを作成する。
-ポイント
--combineReducersをココで書いている。
--applyMiddlewareで、~
Reduxの状態遷移をコンソール上に表示する~
redux-logger ミドルウェアを追加する。
-参考
--Qiita
---ReduxのreducerもHot Reloadingさせる方法~
https://qiita.com/wadahiro/items/30f7f6a45af19f3ae9c1
***Reducer作成(仮) [#f322ef52]
-仮のReducerを作成
-Counter、FetchDataの順にモジュールを追加
***[[Redux]]の組込 [#l64ccec4]
-index.jsに組込む。
--createStoreして、storeを生成する。
--AppContainerタグをProviderタグでラップしつつstore属性にstoreを設定。~
(以下のようなスニペットを発見したので、そのまま適用)
ReactDOM.render(
<Provider store={store}>
<AppContainer />
</Provider>, ・・・
-ここで一度 npm start コマンドを実行し動作することを確認。
***Component作成 [#sa661065]
作成済みなのでココでは何もしない。
***Action作成 [#l4ebab9a]
-Actionを作成
-Counter、FetchDataの順にモジュールを追加
***Reducer修正 [#g6ecabce]
-Reducer(仮)のreducers/Counter、FetchData.jsにActionに対応した処理を実装する。
-Actionから渡された値を「処理して」Componentに渡す。の処理の部分。
-ポイント
--初期値はinitialStateで定義して使用する。
--state は書き換えるのではなく新たなオブジェクトとするので、~
Object.assignでディープコピーし、それに値を設定し、戻り値とする。
--redux-thunkによる非同期処理を実装する。
-参考
--reduxで非同期処理をするいくつかの方法(redux-thunk、redux-saga)~
https://qiita.com/m4iyama/items/63386fd65c7e9f06f5d4#redux-thunk
***Container作成 [#gad2a8bd]
-containers/Counter、FetchData.jsを作成する。
-そして、routes.jsを修正してCounter、FetchDataをComponentからContainerに切り替える。
-ポイント:ここでconnectする。
***Component修正 [#o4ef6ca6]
-components/Counter、FetchData.jsで、propsのstateとfunctionを参照するように変更する。
**実行 [#vc6436a4]
**サンプル [#g981bbfd]
**参考 [#q01ddb23]
-reduxで非同期処理をするいくつかの方法(redux-thunk、redux-saga)~
https://qiita.com/m4iyama/items/63386fd65c7e9f06f5d4#redux-thunk
-ReduxのreducerもHot Reloadingさせる方法~
https://qiita.com/wadahiro/items/30f7f6a45af19f3ae9c1
-Access Route Params in React Router v4 | Jake Trent~
https://jaketrent.com/post/access-route-params-react-router-v4/
*参考 [#v94b3eeb]
**[[Reactのファースト・ステップ]] [#s8192f13]