はじめに
早くも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 Creators
Action
を作成するメソッド
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 Component
Presentational 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の実装について見ていきます。