Browserify, Babelify, React, Arda で画面遷移を表現する その2


# 前回までのあらすじ

React をお試しでやるだけであれば、公式のチュートリアルをやれば、scriptタグで読み込みをした環境で手軽に実行できますが、実際の開発でそんなことはしないでしょう。

従来のような開発方法でも実装は可能でしょうが、React はコンポーネント志向で、モジュールをたくさん作っていくような実装をするため、モジュールシステムが必要不可欠なのではないかと思います。

前回までは、その為の下地作りでした。

# Reactコンポーネントの表示

次にようやく、React による制作デモに入っていきます。

一旦前回の例で作ったコードは全部削除して、以下のコードに置き換えます。

また、html には body 直下に ```<div id=“app”>``` という、コンポーネントをレンダリングする場所を用意してください。

```
// src/main.js
global.React = require('react');

var Main = React.createClass({
  render: () => {
  return (
     <div>
        main component
     </div>
    )
  }
});

React.render(
  <Main />, document.getElementById('app')
);
```

global においているのは後で使う Arda の都合です。
まずは簡単に、コンポーネントを一つ描画してみました。

JSX のことは省略しますが、Browserify を通すとこれもよしなに扱ってくれるので特に気にせず記述しました。
画面には、```main component``` と表示されます。

# Ardaに乗っかる

ではこれを Arda に乗せてみます。

```
global.React = require('react');
var Arda = require('arda');

var Main = React.createClass({
  mixins: [Arda.mixin],

  render: () => {
    return (
      <div>
        main component
      </div>
    )
  }
});

class MainContext extends Arda.Context {
  get component() {
    return Main;
  }
}

var Router = new Arda.Router(
  Arda.DefaultLayout,
  document.getElementById('app')
);

Router.pushContext(MainContext, {});
```

ちょっと複雑になりましたが、コンポーネントをコンテキストに包まれて、それをルーターにプッシュすることで表示しています。

これが、コンポーネントを画面に表示する基本型のようです。

# コンテキストの切り替え

Arda に乗ったところで、別のコンポーネントへ切り替えるというようなことをしてみます。

```
global.React = require('react');
var Arda = require('arda');

var Main = React.createClass({
  mixins: [Arda.mixin],

  onClick: function (ev) {
    this.dispatch('main:go-to-sub');
  },

  render: function () {
    return (
      <div>
        <h1>Main Component</h1>
        <button onClick={this.onClick}>Go to sub</button>
      </div>
    )
  }
});

var MainSubscriber = Arda.subscriber(function(context, subscribe){
  subscribe('main:go-to-sub', function () {
    Router.pushContext(SubContext, {});
  });
});

class MainContext extends Arda.Context {
  get component() {
    return Main;
  }
  get subscribers() {
    return [MainSubscriber];
  }
}

var Sub = React.createClass({
  mixins: [Arda.mixin],

  onClick: function (ev) {
    this.dispatch('sub:go-to-main');
  },

  render: function () {
    return (
      <div>
        <h1>Sub Component</h1>
        <button onClick={this.onClick}>Go to main</button>
      </div>
    )
  }
});

var SubSubscriber = Arda.subscriber(function(context, subscribe){
  subscribe('sub:go-to-main', function () {
    Router.popContext();
  });
});

class SubContext extends Arda.Context {
  get component() {
    return Sub;
  }
  get subscribers() {
    return [SubSubscriber];
  }
}

var Router = new Arda.Router(
  Arda.DefaultLayout,
  document.getElementById('app')
);

Router.pushContext(MainContext, {});
```

補足: ( ```() => {}``` の記述は、this が変わるようでうまく動作しなかったので、結局 ```function() {}``` に書きなおしました…やっぱりthisをよく理解出来てない)

一気にコードが増えました。

まず、Subコンポーネントを作りました。中身はMainコンポーネントと代わりません。

コンポーネントにはボタンを置き、それをクリックすると、```this.dispatch()``` でイベントが飛ぶようになりました。

また新しい、Subscriber という登場人物も出てきています。
見ての通り、dispatch されるイベントをキャッチしてます。
これもコンテキストで包まれます。

Main でボタンを押すと、Sub がコンテキストのスタックに積まれます。
(ココらへんがAndroidのActivityのスタックに似てるところ)
Sub でボタンを押すと、Sub のコンテキストがスタックから取り除かれます。

ひとまず、Arda に乗っかった画面遷移が実現できたように思えます。

# おわり

今回は一枚のファイルに全部書いてしまったので、各コンポーネントやコンテキストを変数名で避けたりしてますが、モジュール化で中に閉じ込めてスッキリさせることも出来そうです。

フロントエンド界隈は本当にサイクルが早いですが、どんな言語でも根本をキチンと掴んでいれば、なんとか付いていけそうですね。
(掴んでいれば、掴んでいればな…)

まだ React もちょっと触ったくらいなので、これをベースに props や state が絡んできた時にまたどうなることやら…という感じですが、ひとまず色々と考えを整理出来たので成果があったということにします。

ES6 については、結局サンプルコードでは使いませんでした。
アロー関数の this の扱いが function と異なるので、サンプルの見まねで動かせなかったりしたので、結局戻してしまいました。

ひとまず babelify で解決できる環境は用意できたので、
```let``` や ```const```、新しい関数などはそれほど引っかからず使えそうなので、機会があれば取り入れてみたいかと。

最後まで呼んでいただいた方、ありがとうございました。
また進展があったら書いてみたいと思います。