Reactのチュートリアル(TODOアプリ)に alt を適用した


## 背景
flux を使ってみたくて、最初はフレームワークを使わずに実装してみた。特に不満はないものの、フレームワークを使ってみるとどのような効果があるのかな？と試してみたくて、[alt](http://alt.js.org/guide/)を適用してみた。
altは、活発にメンテナンスされており、商用としてつかわれている実績もあるようだ。

> * It is pure flux. Stores have no setters, the flow is unidirectional.
* Isomorphic and works with react-native.
* Actively maintained and being used in production.
* Extremely flexible and unopinionated in how you use flux. Create traditional singletons or use dependency injection.
* It is terse. No boilerplate.

## 感想
> [altを少しかじって](http://alt.js.org/guide/)いないと、書いてあることの意味が掴めないかもしれません。

### ストレートにFluxを適用するよりも便利だな、と感じたこと
#### アクションタイプをわざわざ定数化したり、ボイラープレートを用意する必要がない
アクションを定義するためにストア内部に実装するのは、

```javascript
destroy (id) {
return id;
}
```

これだけ。altが公開している関数 `createActions` に包むことで、自分が実装したアクションを強化してくれるから、これだけで済む。
ちなみに普通に書くとこのようになる。

```javascript 
destroy: (id) => {
  AppDispatcher.dispatch({
    actionType: TodoConstants.TODO_DESTROY,
    id: id
  });
}
```

```javascript
import keyMirror from 'keyMirror';

module.exports = keyMirror({
  TODO_CREATE: null,
  TODO_COMPLETE: null,
  TODO_DESTROY: null,
  TODO_DESTROY_COMPLETED: null,
  TODO_TOGGLE_COMPLETE_ALL: null,
  TODO_UNDO_COMPLETE: null,
  TODO_UPDATE_TEXT: null
});
```

`actionType` 向けに、定数を用意している。また、ディスパッチするために `AppDispatcher.dispatch`を呼び出している。

#### ストア内部の `switch` を記述しなくても、ハンドラとバインドする仕組みがある
ストア内部に、 `bindListener` を記述することで、 alt がハンドラとアクションを関連づけてくれる。

```javascript
this.bindListeners({
  handleCreate: TodoActions.CREATE,
  handleUpdateText: TodoActions.UPDATE_TEXT,
  handleToggleComplete: TodoActions.TOGGLE_COMPLETE,
  handleTodoUndoComplete: TodoActions.TODO_UNDO_COMPLETE,
  handleTodoComplete: TodoActions.TODO_COMPLETE,
  handleToggleCompleteAll: TodoActions.TOGGLE_COMPLETE_ALL,
  handleDestroy: TodoActions.DESTROY,
  handleDestroyCompleted: TodoActions.DESTROY_COMPLETED,
  handleUpdateTodos: TodoActions.UPDATE_TODOS,
  handleTodoFailed: TodoActions.TODO_FAILED,
  handleFetchTodos: TodoActions.FETCH_TODOS
});
```

普通は、[このような `switch`文を用意](https://facebook.github.io/flux/docs/todo-list.html#creating-stores)する。

```javascript
dispatcherIndex: AppDispatcher.register(function(payload) {
  var action = payload.action;
  var text;

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

    case TodoConstants.TODO_DESTROY:
      destroy(action.id);
      TodoStore.emitChange();
      break;

    // add more cases for other actionTypes, like TODO_UPDATE, etc.
  }

  return true; // No errors. Needed by promise in Dispatcher.
})
```

#### ストア内部で `change` イベントを明示的に発火しなくて良い
> Stores automatically emit a change event when an action is dispatched through the store and the action handler ends.

上記のコードからもわかるように、`change` イベントを明示的に記述する必要はない。ストア内部で自分が書くコードは、特定のアクションのハンドラだけである。

```javascript
//単純に、ペイロードとして渡される値について処理するだけ
const destroy = (id) => {
  delete _todos[id];
}
```


#### 非同期通信時の状態をコントロールできる
ソースモジュールに、非同期通信のローディング時、成功時、失敗時のそれぞれに対応するアクションを設定できる。また、`isLoading()`を使うことでコンポーネントを制御し、ローディング中は画像を表示させるなどの分岐を簡単に、Functional に実装することができる。

```javascript
// 非同期処理を扱う、ソースモジュール
// 非同期であるfetchTodos関数を、success/error/loading にそれぞれ関連付けたアクションを使って実現する
// 
const TodoSource = {
  fetchTodos() {
    return {
      remote(state) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            if (true) {
              resolve(mockData);
            }else {
              reject('Things have broken');
            }
          }, 500);
        });
      },

      local() {
        return null;
      },

      success: TodoActions.updateTodos,
      error: TodoActions.todoFailed,
      loading: TodoActions.fetchTodos,

      shouldFetch(state){
        return true;
      }
    };
  }
}
```


```javascript
// Component#render()内のコード
if(TodoStore.isLoading()) {
  return (
    <div>
      <img src="ajax-loader.gif" />
    </div>
  )
}
```

### altの思想
Fluxの考え方を踏襲している。

> The basic idea is that you have a container that wraps your component, the duty of this container component is to handle all the data fetching and communication with the stores, it then renders the corresponding children. The sub-components just render markup and are data agnostic thus making them highly reusable.

コンテナとなるコンポーネント以外は状態を持つことなく、与えられたデータによってのみDOMを`render`することで、コンポーネントは高い再利用性を持つ。これは alt に限ったことではなく、 Flux の思想と言える。

### mixinというものに初めて触れた
altの[StoreMixin](https://docs.omniref.com/js/npm/alt/0.13.11/symbols/StoreMixin)というモジュールによって、いろいろと便利な関数が自分の書いたストアに追加される。
これがどのようなことを意味するかというと、全く定義していない（ように思える)関数を、自分がストアに記述するということになる。実行時にこの関数が追加されるため、コードを書いている時点では少々、頭の中にハテナが浮かぶ。これは慣れるしかないか。

ただし、ES6からは mixin をサポートする機能が React から落とされているので、今後は別の手段で問題解決するのが主流となる。

### HOC (High Order Component) に触れた
別の手段というのが、この HOC のことで、詳しくはこちらに書いてある。
[Mixins are Dead.](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750#.6bo9kqbzl)

HOCの特徴は合成で、React ではあるコンポーネントを起点として、新たなコンポーネントを作ることを指す。この合成は繰り返すことができる点も利点としてあげられる。

ところで、もともと mixin や HOC は、Reactにおいては大きく2つの重要な役割を担っている。

* ユーティリティ関数を提供する
* 共通のライフサイクル関数( lifecycle hook )を提供する

その際に、mixinの持つ次のような課題を解消する期待を持たれているのが HOC ということだ。

* mixin とコンポーネントとの依存関係が暗黙的
* 一つのコンポーネントに mixin を多用するとクラッシュする可能性がある
* mixin は、本来できる限り少なくすべき`state`を増やす傾向がある
* パフォーマンスチューニングを複雑にする

> React準拠でドラッグアンドドロップを制御する[React DnD](https://gaearon.github.io/react-dnd/)も似たような作りになっている。


### テストコード
まだ書いていない・・。

## まだちょっと理解が追いついていないこと
. BootStrap/Snapshot などのAPI
. Isomorphic な alt の利用シーン
. [altjsのリポジトリ](https://github.com/alt)の使い方


## サンプルコード
https://github.com/rooooomania/new-todo

> https://facebook.github.io/react/docs/flux-todo-list.html
このチュートリアルのコードを、次のステップで修正していった。

> 1. ES6化
> 1. alt の適用