ReactなComponent同士を連携させたい
実践的なサンプルに塗れてなんとなく使ってると破綻する。
分かってること、分かってないことを整理しておきたい。
Contents
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側に変更が通知される。
1 2 3 4 5 6 7 8 9 10 |
var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> <Comment author="Pete Hunt">This is one comment</Comment> <Comment author="Jordan Walke">This is *another* comment</Comment> </div> ); } }); |
CommentコンポーネントはCommentListから渡されたauthorとchildrenを参照して表示するようにしておく。
propsというプロパティが外から与えられた引数を抱えている。
1 2 3 4 5 6 7 8 9 10 11 12 |
var Comment = React.createClass({ render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> {this.props.children} </div> ); } }); |
このように、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)を実行すれば親に通知できる、という流れだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var CommentBox = React.createClass({ // blah blah blah... handleCommentSubmit: function(comment) { // TODO: submit to the server and refresh the list }, // blah blah blah... render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } }); |
CommentFormコンポーネントの実装はこんな感じ。
注目すべきはhandleSubmit内の処理。
this.props.onCommentSubmit({author: author, text: text});
ここでコールバックを実行してる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = React.findDOMNode(this.refs.author).value.trim(); var text = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({author: author, text: text}); React.findDOMNode(this.refs.author).value = ''; React.findDOMNode(this.refs.text).value = ''; return; }, render: function() { return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text" /> <input type="submit" value="Post" /> </form> ); } }); |
孫から親への通知
孫から親、といった階層深い関係間の通知だけでなく、兄弟間の通知も上述ようなコールバック形式でやろうとすると実装が複雑になる。
じゃあ、どうしようか。
って話。
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アーキテクチャ。
336px
336px
関連記事
-
-
FlutterでListViewしたい
こん …
-
-
フロントエンド開発のメモ
最近 …
-
-
Docker導入したらどうするの?
Do …
-
-
goで無限ループ
しょ …
-
-
RDSの特定のデータベースをダンプする
Pu …