アプリケーションの開発において、ビューの構築にReactを導入する際、Fluxアーキテクチャを採用することで、構築をよりスマートに行なえるようになります。 今回は、このFluxアーキテクチャについて、その概要をまとめました。

Fluxアーキテクチャとは

Fluxは、一方向のデータフローを採用した、Reactのためのアプリケーションアーキテクチャです。

アプリケーションをActionやDispatcherといったドメインに分割し、メッセージパッシングによってドメイン間のメッセージの流れる方向を一方向に制限することで、疎結合・非同期にUIを構築することができます。

ユーザからの入力があると、そのメッセージを購読するビューが自動で更新されるため、状態の複雑な管理などを回避することができます。

解決する課題

従来のMVCは、モデルとビューの間に双方向のデータフローがつくられる可能性があります。 つまり、モデルやビューが増えると、指数関数的に複雑さが増してしまいます。 このことは、アプリケーションを壊れやすく、予測不可能なものにしてしまいます。

これに対する解決策は、予測可能な形でコードを構造化することであり、FluxアーキテクチャとReactによってこれを実現しています。

4つのドメイン

Fluxアーキテクチャには、主に以下の4つのドメインがあります。 それぞれについて簡単に説明します。

Action

まず、ActionCreatorsというドメインで、Viewに対するユーザの入力を待ち受けます。 やってきた入力をもとに、Dispatcherへのメッセージ発行処理を行ないます。

これをまとめてActionとして提供します。

Dispatcher

Actionをトリガーとして、Storeに対してメッセージを発行します。 アプリケーションに1つのみ存在します。

Store

Dispatcherにコールバックを登録しておき、関連するメッセージを受け取ります。 このメッセージに応じて、アプリケーションの状態を管理します。

View

Storeからのメッセージを購読し、それに応じてユーザに対して出力を返します。

この一連の動きをまとめると、以下のようになります。

ユーザの入力をActionが受け取り、それをもとにDispatcherにメッセージを送る。

StoreはDispatcherにコールバックを登録しておき、そのコールバックに関連するメッセージをDispatcherがActionから受け取った場合、Storeの状態が更新される。

Storeが更新されたら、そのStoreの状態変更を購読しているViewが自動で更新され、ユーザに更新されたUIを提供する。

この繰り返しを実現するのがFluxアーキテクチャである。

実装例

Fluxアーキテクチャ実装のフレームワークとして、同名のfacebook/fluxがあります。 このフレームワークを用いた実装例が公式リポジトリにあるので、参考にしてください。

以下に、ToDoアプリケーションの「作成」に関する処理を一部抜粋して示します。

Action

var TodoActions = {
  create: function(text) {
    AppDispatcher.dispatch({
      actionType: TodoConstants.TODO_CREATE,
      text: text
    })
  }
}

Dispatcher

var Dispatcher = require('flux').Dispatcher;

Store

var _todos = {};

function create(text) {
  var id = (+new Date() + Math.floor(Math.random() * 999999)).toString(36);
  _todos[id] = {
    id: id,
    complete: false,
    text: text
  };
}

var TodoStore = assign({}, EventEmitter.prototype, {
  getAll: function() {
    return _todos;
  }
});

AppDispatcher.register(function(action) {
  var text;

  switch(action.actionType) {
    case TodoConstants.TODO_CREATE:
      text = action.text.trim();
      if (text !== '') {
        create(text);
        TodoStore.emitChange();
      }
      break;
  }
});

View

function getTodoSate() {
  return {
    allTodos: TodoStore.getAll()
  }
}

var TodoApp = React.createClass({
  getInitialState: function() {
    return getTodoState();
  },

  render: function() {
    return (
      <div>
        <Header />
        <MainSection allTodos={this.state.allTodos} />
        <Footer allTodos={this.state.allTodos} />
      </div>
    );
  }
})

おわりに

Reduxなど、Fluxを参考にしたフレームワークが多く存在しますが、「Fluxアーキテクチャからどの程度離れているか」という基準で考えると分かりやすいと思います。

上記を理解しておくことで、Flux関連の技術のキャッチアップに役に立つと思うので、ぜひ参考にしてみてください。