6)Flux
UI開発が小規模の場合、コンポーネント化していけばなんとかなってしまうものですが、規模が大きくなってくると、様々なコンポーネントが複雑に関係し合いイベント地獄に陥ってしまいます。
Facebookはこの問題を解決するためにFluxアーキテクチャを考え出しました。
上図はFluxアーキテクチャを示しています。それぞれの役割は下記の通りです。
名称 | 役割 |
---|---|
React Views | React.createClassで定義したUI |
ActionCreators | アクションメソッドを持つクラス。UIからStoreの値を更新するためには、このクラスを必ず経由しなければいけない。 |
Dispatcher | アクションが実行されたことを通知するためのイベント管理クラス |
Store | アプリケーションが必要とするデータを格納するクラス。Dispatcherのイベント通知を受けて値を更新する。 |
このような説明を書かれてもなかなか理解は進まないと思うので、ReactRadarScopeで実例を交えながら説明します。
まず、UIコンポーネントであるDotクラスを見てみます。DotはOSS Radar Scope®の順位を示す丸です。
このDotにマウスが乗ったときに、以下のコールバックが呼ばれます。
RadarActionupdateSelectedOssthispropsproductid;
これがReactViewsからActionCreatorsへの矢印になります。
そして、RadarAction.updateSelectedOss
では次のようにdispatcherを実行します。
RadarDispatcherdispatchactionType: ConstantsUPDATE_SELECTED_OSSossId: ossId;
この例だとWebAPIへの矢印がありませんが、そのまま直接RadarDispatcher.dispatchを呼んでいます。
RadarStoreがRadarDispatcherに対してコールバックを指定しているため、RadarStoreに処理はうつります。
RadarDispatcherregisterswitchpayloadactionTypecase ConstantsUPDATE_SELECTED_OSS:_selectedOss = parseIntpayloadossId 10;RadarStoreemitChange;break;default:return true;return true; // No errors. Needed by promise in Dispatcher.;
この例であれば、_selectedOssの値を更新し、RadarStore.emitChange()を実行します。 MainコンポーネントがRadarStoreのイベントハンドラを定義しているため、変更はMainコンポーネントに通知されます。
RadarStoreaddStoreChangeListenerthis_radarStoreChange;thissetStateselectedOssId: RadarStoregetSelectedOss;
Mainコンポーネントは通知された値をsetState
してstateを更新します。するとselectedOssIdを使用している子コンポーネントが再描画されます。
一見まどろっこしいですが、データフローが1方向なのでアプリケーションがシンプルに保つことができます。規模が大きくなればなるほどこのアーキテクチャの有効性が際立ちそうです。
逆に小さいアプリケーションではそんな重厚なアーキテクチャはソースコードの行数を増やすだけであり、嬉しさを実感できないと思います。