React-Redux 入門日記

React-Redux 入門日記

2017年3月22日

勉強中のコードなのであまり参考にならないと思うが,コードはGitHubリポジトリ /daiz713/MyExpressAppに置いてある.アプリのフレームワークにNode.jsExpressを使って,ViewにReact+Reduxを採用している.データベースは以前使ったことにある MongoDB にしようと思ったけれど Google Cloud Datastore が Google App Engine 以外のウェブアプリからも呼び出せることを知ったので Datastore にした.(Datastoreは今回の範囲ではまだ使わない)

リポジトリのREADMEに書いてある /album というのが一番新しい練習作品で,最近Gyazoった写真を表示するミニアルバムアプリ <Album /> となっている.Reactコンポーネント <Album /> 内には,いくつかコンポーネントが内包されているが,メインとなるのは <GyazoImage /> <GyazoImageList /> で,これらに渡る props を更新していくことで画面の描画内容を変化させられる.ユーザーのクリックイベントなどに基いて ActionCreator が Action (単なるJSオブジェクト) を発行し,Reducer と呼ばれる関数が Action の type に応じて次にセットすべき state (props?) を返す.これに基いてコンポーネントの render 関数が差分を描画する.この仕組みは面白い.


ここまで理解してくると,非同期でない処理は書けそうな気がしてきて,やってみると意外とすんなりと実際に書ける.しかし,今回のお題はGyazoアルバムを作ることなのでどこかで Gyazo API を呼ぶ必要がある.色々調べていくと,Action と Reducer の間に噛ませる Middleware である react-thunk を使うと良いらしいことが分かる.これを用いると,ウェブAPI呼び出し〜読み込み完了の状況に応じて非同期的に Action を発行 (dispatch) する fetchGyazoImagesAsync のようなActionCreatorが書けるようになる. <GyazoImageList /> が componentDidMount になったときに関数fetchGyazoImagesAsyncを呼び出すことで,画面表示のタイミングで自然とAPIコールが始まった.これまであまり意識していなかったが,APIを呼び出してから目的達成するまでには,以下のような状態が考えられる.
取得中
-> 成功
-> 失敗
これらの情報を詰め込んだ Action を逐一発行すれば,ロード中のアニメーションも作りやすいかもしれない.
無事に画像リストの取得が完了したら, <GyazoImageList /> 内に <SquareThumbnail /> を新規生成していく.これにクリックイベントを仕掛けたいときは,GyazoImageList の props に予めhandler関数を与えておき,SquareThumbnail でその関数を参照させる,というふうにやっている (これが正しい方法であるかはまだ自信がない).一番上層まで参照が伝わると,関数 mapDispatchToProps で紐付けていた ActionCreator が発動する.この関数が発行する Action によって,写真プレビュー用のReactコンポーネントである <GyazoImage /> の props が更新されて,画面も更新される.

実際にクリックして動かしている様子はこんな感じで,Chrome Devtool である React Developer Tools を入れておくと,クライアントサイドで構築されたReactコンポーネントの props や store の中身などを逐一確認できる. <SquareThumbnail /> 要素をクリックすると <GyazoImage /> の内容が更新される.DevToolでは,更新された箇所が緑でハイライトされる.


ここまでAlbumアプリを書いてきたけれど,
props と state の違いがいまひとつ分からない
コンポーネント間で props 受け渡しリレーみたいなことが起こっていて鬱陶しいのだけど,こんなもんなのだろうか.
props と state を紐付けている(?) mapStateToProps の書き方がだいぶ面倒くさいけれど,本当に現状の書き方で合っているのか
のような疑問が残った.次回の練習作品で解決したい.
Powered by Helpfeel