moxt

Just another Blog site

ReactなComponent同士を連携させたい

   

実践的なサンプルに塗れてなんとなく使ってると破綻する。
分かってること、分かってないことを整理しておきたい。

Reactとは何者か

公式サイトに載ってるコピーは次のとおり。

A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES

UIを構築するためのライブラリ。
なのでMVC,MVVMフレームワークではない。

Componentという単位でUIを抽象化して扱う。
Componentを組み合わせることでアプリケーションを構築していく。
公式サイトのTODOアプリの実装例をみると全体像を把握できる。

  • 表示系の処理はrender
  • stateでComponentの状態を管理する
  • propでComponentに引数を渡す
  • Componentが複数Componentを抱えることができる

Component間の連携はどのように実現するのか

「子のComponentをクリックしたら親のComponentが○○する」というヤツ。
各Componentが完全に独立していれば考えなくてよいが、アプリケーションの仕様が複雑になるとComponent間の依存が発生する。

親から子への通知

http://facebook.github.io/react/docs/tutorial.html#using-props

CommentListコンポーネントはCommentコンポーネントに対してauthorとchildren(Commentタグの中身)を渡している。
CommentList側でauthorやchildrenが変わるとComment側に変更が通知される。

CommentコンポーネントはCommentListから渡されたauthorとchildrenを参照して表示するようにしておく。
propsというプロパティが外から与えられた引数を抱えている。

このように、propsを介すことでComponent間の連携を実現している感じだろうか。
親の変化を子に通知するためにはpropsを使えば良さそう。

子から親への通知

クライアント系の実装でよくみる手法は次のとおり

  • 親の参照(何らかのインタフェース)を渡しておき、親に通知したいタイミングでCallbackを実行
  • EventBusを介して通知をやり取りする

http://facebook.github.io/react/docs/tutorial.html#callbacks-as-props

これを見ると前者のCallback形式で親への通知を実現しているようだ。

以下のCommentBoxコンポーネントはCommentFormコンポーネントを内包している。
CommentFormのpropsにonCommentSubmitというキーで、handleCommentSubmitという関数を値として渡している。

で、CommentFormコンポーネントの中でthis.props.onCommentSubmit(comment)を実行すれば親に通知できる、という流れだ。

CommentFormコンポーネントの実装はこんな感じ。

注目すべきはhandleSubmit内の処理。
this.props.onCommentSubmit({author: author, text: text});
ここでコールバックを実行してる。

孫から親への通知

孫から親、といった階層深い関係間の通知だけでなく、兄弟間の通知も上述ようなコールバック形式でやろうとすると実装が複雑になる。
じゃあ、どうしようか。
って話。

EventBus

上述のとおりコンポーネントが親と子の関係であればコールバックで良さそう。
一方で、親>子>孫という関係で孫から親に何か通知したい、といった感じでネストが深ると面倒。
親と孫との間でコミュニケーションをしたいのに、子を挟まないといけなくなって煩雑になる。

EventBusのような仕組みを使ってコミュニケーションを取るのだろうか。。
ググった結果、以下のような記事を見つけた。

React.js : communication between components

EventBusな例。
通知機構はjQueryを使ってる。
Reactのライフサイクルに応じてon,offを付与して、必要に応じてtriggerで通知してる。

Rails and React IV: Independent components communication

こちらもEventBusな例。
PubSubJSというライブラリを使ってる。

Flux

もしかして…Fluxの出番なのか。

Fluxに関して無知なので、理解の足場的なメモだけ。

Fluxはアーキテクチャ。
MVCとかMVVMと同じレイヤーの存在。
実装は別にある。
ECMAScriptとjavascriptみたいな関係。

Fluxを構成する3大要素は以下のとおり。

Flux applications have three major parts: the dispatcher, the stores, and the views (React components).

  • Dispatcher
  • Store
  • View(React Components)

ReactはFlux構成員Viewの実装ってこと。

FacebookのFluxアーキテクチャの始め方 Part 1 | プログラミング | POSTD

簡単に言うと、Fluxは美化された出版-購読型モデルのアーキテクチャです。

Fluxの実装を使っておくのがよさ気な雰囲気だしてきてるね。

まとめ

現状の理解をさらっと。

ReactのComponent間の連携はpropsを用いる

  • 親から子への通知 : 親が子に必要な要素をpropsを介して渡す
  • 子から親への通知 : 親が自身の関数をpropsを介して子に渡す、子はpropsに詰め込まれた親の関数を呼ぶ(コールバック)

アプリケーションの複雑さに応じて『propsを使った親子間通知』と『Fluxアーキテクチャ』を使い分ける

簡単なアプリケーションであれば、propsを使った親子間通知で連携させれば仕様を満たせそう。
複雑、大規模なアプリケーションになるとpropsを用いた通知手法だと記述が増えて複雑化する。
この複雑さに立ち向かうのがFluxアーキテクチャ。

 - プログラミング

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

  関連記事

no image
単語の出現頻度をlinuxコマンドだけで調べたい

無駄にpythonとか使おうとしてた。。 楽にできて良かった。 …

scrapy実行時のエラー対処

Macで発生した。 scrapyを実行したら下記のようなエラーを吐いた。 …

nokogiriでスクレイピングするときによく忘れるヤツ集

書くことで記憶を定着させる施術。 class,id以外の属性を指定してタグを探したい …

no image
NginxとPHP-FPMを使っていたらcurl_init()が無いとエラーが出た

参考リンク 解決策 …

Docker Machineのメモ

随時追記する Contents1 …

no image
SwiftでOSのバージョンが8.0.0以下とそれより大きいヤツで処理を分岐させたい

前置き push通知のデバイストークン取得方法がiOS8から変わりました。 …

no image
RDSの特定のデータベースをダンプする

Publicly Accessibleがyesならどこからでも下記が実行可能。 …

no image
意識低いRuby on Rails再入門4

下記の内容を読んでテスト系の処理をすっ飛ばしたメモ。 http://railstutorial.jp/chapters/sign-in-sign-out?version=4.0#top …

ReactNativeでGiphyのデータを表示する

まずは下記をサクッとパクってみる。 当方、比較的AndroiderなのでAndroidで。 …

Ruby,Railsのチートシート

こういうのブログ形式じゃなくてwikiの方が良いのでは。。 と、遠い目をしつつ。 …