Push: Ctrl+Y

 技術で遊んで ときどき進む

React+Redux入門 解説してみた

React + Redux入門① - Reduxの概念を理解

2016/07/26

React+Reduxでサイトを作っているので、復習がてら「検索画面を作成する」のを目標に全5回で解説します。

私はもともとサーバーサイドの人間でjQueryくらいしか使ったことなかったのですが、React+Reduxの組み合わせはかなり使いやすいです。
フレームワークなしで作っていた頃のような不明瞭な動きをしないので、サーバーサイドプログラマに優しい気がします。
ただ最初の概念的なものを理解するまでに結構もがいたので、そのあたり本記事で自分なりに解説できたらなあという気持ちです。

 

入門編の目標

以下のように、最終目標と今回の目標を設定します。

最終目標:検索画面を作成

  • [サーバーサイド] Node.js (Express, MongoDB)
  • [フロントエンド] React.js + Redux + Material-UI

という構成で、検索(DBから取得)画面を作成します。
(Material-UIを利用するのは、そのほうが実装が楽だからです。
私はアイコンすら作るの難しいと感じるので、こういうツールがあるとすごく便利)

今回の目標:Reduxを理解する

今回はReact+Reduxのコードを理解できるようにすることが目標です。
学習コストが高いとよく言われていますが、一度分かると「なんで分からなかった?!」と思うくらい手に馴染みます。
念頭に置いておくと良いポイントは、

  • 今まで:ユーザーアクション -> 処理を開始 -> 処理終了 -> 終了検知後の処理にて画面変更(変更内容はいちいち規定)
  • 当構成:ユーザーアクション -> 処理を開始 -> 処理終了 -> データ(Store)の変更を検知 -> 自動で画面変更

という違いがあるということです。
処理終了後に「完了しました」というメッセージを出すにしても、今までは終了後処理に alert('完了しました'); を書いていましたが、React + Redux ではあらかじめアラートダイアログ自体に Store.message に文字列が入っていたらdisplay: 'block' というステータスを持たせておく、みたいな実装になります。

 

Redux入門

Reduxの大きな流れ

redux-1-1

Reduxの大きな流れとして図示されるものはだいたいこんな感じです。
ぱっとみても何をしているのか分からないので、シュタインズゲートで例えます!
(シュタインズゲート知らない方は、

  • 過去にメールを送信することで現在世界が変化する物語
  • 以下に出てくる「フェイリス」は人名

ということだけ押さえていただければ分かるかなと)

redux-1-2

  1. 今の世界(中身:Store/表現:ReactComponent)では、
    ・フェイリスの父親は亡くなっている(store.isFatherAlive=false
    ・秋葉原は萌え文化が盛ん(父不在の寂しさを紛らわすためにフェイリスが提案したことで萌え文化が広まったため)(store.isAkibaMoe=true
  2. フェイリスが父親の死を回避するためのメールを過去の自分へ送った(@React Components
  3. 過去へメールを送信するというActionを受けて、ActionCreatorが必要な情報(↓)を算出
    ・過去のフェイリスがその情報を受け取ったら父は生存する(action.isFatherAlive=true
    ・父が生存したら秋葉原の萌え文化は提案されない(action.isAkibaMoe=false
  4. Reducerが今の世界とActionCreatorから受け取った情報で次の世界の形を決め(↓)、Storeを変更
    ・フェイリスの父親は生きている(store.isFatherAlive=action.isFatherAlive
    ・秋葉原に萌え文化は存在しない(store.isAkibaMoe=action.isAkibaMoe
  5. Storeが変更されたことにより、ReactComponent世界の表現)も自動的に変化する

大体この流れさえ押さえてしまえば、迷子になることはないです。

 

 

コードを追うために必要な知識

上記の話をソースコードに落とすとどうなるかを例にして、GitHubのコードを読めるようになるくらいを目標に解説します。ある程度ソースコードを読めるようになったら、スターがたくさんついているGitHubのソースを見ながら勉強するのが一番の早道です。

 

ディレクトリ構成

Reduxのディレクトリ構造は大体こんな感じになっていると思います。
詳しくは②以降で解説するのでここではざっくり説明しますが、
最初に参照するのはpagkage.jsonというファイルです。

Node.jsではnpmというコマンドでモジュールをインストールしたり動かしたりします。
大体の場合、サーバーを動かすためにnpm startというコマンドを利用しますが、
そのコマンドの実行内容を記載しているのがpackage.jsonというファイルのscripts.startになります。

ちなみに私が今作っているものの記載はこんな感じで、

devServer.jsというファイルを実行してExpress(Node.jsのフレームワーク)でサーバーを立ち上げています。
ざっくりと、
・actions以下にActionCreaterの中身
・componentsとcontainersの中にReactComponents
・reducers以下にReducer
が入っていると思っていただければ良い感じです。

 

 

ReactComponents

まず、画面の表示内容・動作を記述するReactComponentsからみていきます。
ディレクトリはcontainerとcomponentに分かれていますが、

  • container・・・画面の動作を記述する
  • component・・画面のレイアウトを記述する

という違いがあります。
まず、画面のレイアウトを作るのでcomponentを実装してみます。

componentはかなり単純で、参照すると画面の表示内容が分かります。
動作や表示するデータはすべてpropsとして受け取り、どこでそのデータを使うかを規定するのみです。
画面動作を調べるときは、

  1. ./componentsを見てpropsで流し込まれている動作の名前を確認(onClickSendDmail
  2. 当componentを呼び出しているcontainerを検索
  3. <Top onClickSendDmail={*****} />のような記述を発見したら*****の部分が実際の動作

という流れで探します。
そのcontainerは以下のような実装になります。

componentのTopを呼び出しているところは解説したとおりで、propsとして動作と値を渡しています。
connect()部分がReduxのミソです。
(ちなみにシュタインズゲート的にはデンワレンジだと思っておくと・・)
第一引数のmapStateToPropsはStoreの値が変更(Action -> Reducerにより:後述)されると実行されます。
returnで指定した値が変更されるとTopContainerのpropsの中身も更新され、画面に反映されるという流れです。

第二引数のmapDispatchToPropsはなくても問題ありません。
利用しない場合、handleOnClickSendDmail()でdispatchをいちいち記載しなければならなかったり面倒なので、この方法がシンプルにできて良いかなと思います。

 

まとめとして画面操作からの流れで説明しなおすと以下のとおりです。

  1. Topコンポーネントのボタンをクリック
  2. TopContainerhandleOnClickSendDmail()が実行される
  3. ActionのsendDmail()が実行される
  4. ActionがReducerを呼び出し、Storeが更新される
  5. mapStateToPropsで指定したisFatherAlive/isMoeAkibaが更新される
  6. TopContainerの値が更新され、Topコンポーネントに新しいpropsが渡されるので、画面表示が変わる

 

Action

ボタンを押したときに呼び出されるtopActionBind.sendDmail()について見ていきましょう。

はい、これだけです。
複雑な処理をする場合は結構長くなるのですが、今回はさくっといきます。
returnするものにtypeは必須で、このtypeを持ってReducerに行き、処理内容を探します。

 

Reducer

Reducerでは、新しいState(Storeの中身)を返します。

Reducerは純関数(副作用なし)にする必要があるので、Object.assignを使ってコピーしてreturnします。
ここからTopContanermapStateToPropsに戻って、画面内容が変更されます。

 

まとめ

以上で入門終了です!

次からは実際にモノを作っていきたいと思います。

 

 

-React+Redux入門, 解説してみた
-, ,

おすすめの記事

1
React + Redux入門① - Reduxの概念を理解

React+Reduxでサイトを作っているので、復習がてら「検索画面を作成する」 ...

2
React + Redux + D3.js アニメーション:ドラッグ&ドロップでキングスライムを作った

はい、今回は要素のドラッグ&ドロップを中心に作ってみました。 Mater ...