はじめに
早くも2017年になってしまいましたね。
本年もよろしくお願い致します。
今回はiOSエンジニアが苦しんだReduxの基礎(1)の続きを書いていきたいと思います。
前回はReduxのみを利用したWebサイトの実装について話をしましたが、今回はReactと組み合わせて行きたいと思います。
では早速見ていきましょう。
Counterサンプルで学ぼう!
公式ReduxページのExampleの先頭に書かれている Counter を見ていきましょう。
実現するWebサイトは Counter Vanilla と同じで下図のようになります。

実装されている機能としては下記の4つになります。
- 「+」ボタンを選択するとClick数が+1される
- 「-」ボタンを選択するとClick数が-1される
- 「Increment if odd」ボタンを選択するとClick数が奇数のときのみ+1される
- 「Increment async」ボタンを選択すると1秒後にClick数が+1される
前回と異なるのはViewに React を利用しているという点です。
では1つ1つ見ていきましょう。
フォルダ構成
まずはフォルダ構成を見ていきます。
(説明のために一部変更を加えています。)
1 2 3 4 5 6 7 8 9 10 11 12 | |
Actions
今回Actionsはactions/index.jsにまとめています。
ActionsとAction Creatorsについて復習しておきます。
Actions- 何をするアクションなのかを表すオブジェクト
typeプロパティを必ず持つ
Action CreatorsActionを作成するメソッド
1 2 3 4 5 6 7 8 9 10 | |
Reducers
今回Reducersはreducers/index.jsにまとめています。
Reducersについても復習しておきます。
ActionとStateから新たなStateを作成して返す- ポイントは
Stateを更新するのではなく、 新しく作成したStateを返すということ
1 2 3 4 5 6 7 8 9 10 11 12 | |
Components
今回はReactを利用するので、描画部分を表現するComponentsを作成する必要があります。
ComponentsにはPresentational ComponentとContainer Componentの2種類が存在します。
Presentational Component- 画面の描画を担当する
Component
- 画面の描画を担当する
Container ComponentPresentational Componentにデータやコールバックを渡すComponent
本記事のExampleは簡単なため、Presentational Componentのみ利用しています。
Presentational Componentはcomponents/Counter.jsが該当します。
ソースコードは下記の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
Counter Componentで最も重要なポイントは、
『描画にはvalue, onIncrement, onDecrementの3つが必須』という点です。
Store
今回Storeはsrc/index.jsにまとめられています。
Storeについても復習しておきましょう。
- アプリ内で必ず1つの存在
- アプリの状態を管理する
Stateを更新するためのdispatchを提供する- 言い換えれば
dispatch(action)をすることでStoreにStateの変更を知らせられる
- 言い換えれば
Stateの状態を追えるようにsubscribeを提供する- 言い換えれば
subscribe(listener)をすることでlistenerはgetStateを通してStateの状態を取得できる
- 言い換えれば
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
少し詳しくポイントを見ていきましょう。
冒頭で必要なモジュールを読み込んでいます。
1 2 3 4 5 6 | |
そして、下記のようにstoreを作成しています。
1 2 | |
また、前回はHTMLに全て構成を書いていましたが、今回はReactを利用していますので、下記のように描画をしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Counter Componentの3つの必須propTypesに下記を渡しています。
- value:
Stateの値(store.getState()) - onIncrement:
StoreにStateの増加を通知(() => store.dispatch(increment)) - onDecrement:
StoreにStateの減少を通知(() => store.dispatch(decrement))
上記のようにすることで、
クリックしたタイミングでstore.dispatchにAction Creatorsであるincrementおよびdecrementで作成したActionsを渡せるようになりました。
これにより、『 StoreにStateの変更を知らせる 』ことができます。
その後、render()で描画処理を実行しています。
最後に、listener処理です。
1 2 | |
上記のように、store.subscribeにrenderメソッドを渡すことで、dispatch実行してStateの状態が変化したときに、毎回renderメソッドが実行されることになります。
こうすることで、『 Stateの変更結果として描画に反映させる 』ことができます。
まとめ
さて、前回の素のReduxから、『ReactとReduxをそれぞれ素で利用する』ところまで進んできました。
ここまで割りとすんなり理解できたのであれば、connect()を利用したReact&Reduxの実装の理解までもう少しだと思います。
Reduxの理解を促進する上で重要なのは、
- ユーザの操作結果を
Storeに伝えること Storeの変更に応じて画面を再描画すること
だと思っています。
ここまでの流れさえ理解できてしまえば、応用的な内容も躓かずに理解できるはずです。
さて次回はいよいよconnect()を利用したReact&Reduxの実装について見ていきます。