第2回 簡単なReact.jsの使い方 (6/8)

技術コラム

【第2回】簡単なReact.jsの使い方

OSS Radar Scope

6)Flux

UI開発が小規模の場合、コンポーネント化していけばなんとかなってしまうものですが、規模が大きくなってくると、様々なコンポーネントが複雑に関係し合いイベント地獄に陥ってしまいます。

Facebookはこの問題を解決するためにFluxアーキテクチャを考え出しました。

img/reactjs_flux-diagram-white-background.png

上図はFluxアーキテクチャを示しています。それぞれの役割は下記の通りです。

名称 役割
React Views React.createClassで定義したUI
ActionCreators アクションメソッドを持つクラス。UIからStoreの値を更新するためには、このクラスを必ず経由しなければいけない。
Dispatcher アクションが実行されたことを通知するためのイベント管理クラス
Store アプリケーションが必要とするデータを格納するクラス。Dispatcherのイベント通知を受けて値を更新する。

このような説明を書かれてもなかなか理解は進まないと思うので、ReactRadarScopeで実例を交えながら説明します。

まず、UIコンポーネントであるDotクラスを見てみます。DotはOSS Radar Scope®の順位を示す丸です。

img/reactjs_dot.png

このDotにマウスが乗ったときに、以下のコールバックが呼ばれます。

_onMouseOverfunction(e) {
  RadarAction.updateSelectedOss(this.props.product.id);
},

これがReactViewsからActionCreatorsへの矢印になります。

v2a

そして、RadarAction.updateSelectedOssでは次のようにdispatcherを実行します。

updateSelectedOssfunction(ossId) {
  RadarDispatcher.dispatch({
    actionType: Constants.UPDATE_SELECTED_OSS,
    ossId: ossId
  });
},

この例だとWebAPIへの矢印がありませんが、そのまま直接RadarDispatcher.dispatchを呼んでいます。

img/reactjs_a2d

RadarStoreがRadarDispatcherに対してコールバックを指定しているため、RadarStoreに処理はうつります。

RadarDispatcher.register(function(payload) {
  switch(payload.actionType) {
    case Constants.UPDATE_SELECTED_OSS:
      _selectedOss = parseInt(payload.ossId, 10);
      RadarStore.emitChange();
      break;
    default:
      return true;
  }
  return true; // No errors.  Needed by promise in Dispatcher. 
});

img/reactjs_c2s

この例であれば、_selectedOssの値を更新し、RadarStore.emitChange()を実行します。 MainコンポーネントがRadarStoreのイベントハンドラを定義しているため、変更はMainコンポーネントに通知されます。

img/reactjs_s2v

componentDidMountfunction() {
  RadarStore.addStoreChangeListener(this._radarStoreChange);
},
_radarStoreChangefunction() {
  this.setState({
    selectedOssId: RadarStore.getSelectedOss()
  });
},

Mainコンポーネントは通知された値をsetStateしてstateを更新します。するとselectedOssIdを使用している子コンポーネントが再描画されます。

一見まどろっこしいですが、データフローが1方向なのでアプリケーションがシンプルに保つことができます。規模が大きくなればなるほどこのアーキテクチャの有効性が際立ちそうです。

逆に小さいアプリケーションではそんな重厚なアーキテクチャはソースコードの行数を増やすだけであり、嬉しさを実感できないと思います。