[JavaScript] 仮想DOMを提供する『React』について少し調べてみた


たまに耳にする **React** を自分なりに少し調べてみたので、まとめがてらメモを残します。
ちなみに初めて React を知ったのは [天下一クライアントサイドJS MV*フレームワーク武道会](http://connpass.com/event/6910/)でした。

## Reactとは

**Facebook** のチームが開発している、ユーザインタフェースを構築する為の JavaScript ライブラリです。公式ページ ⇒ http://facebook.github.io/react/

その特徴は（公式ページどおりですが）、

- MVCの **Viewのみ** サポート
	- なので恐らく **他のライブラリと容易に組み合わせ** られる
- **Virtual DOM** (仮想DOM)
- **1方向** の **Reactive** バインディング
	- Reactive .. きっと、(見えないところでシステムが)動的に View を更新する、という雰囲気でしょうか..
	- 公式ページを見ると、やり方によっては双方向にもできるみたい

## Reactの情報

- 公式ページ（上記と同じ）
	- http://facebook.github.io/react/
	- チュートリアルや API ドキュメントなど、わりと充実している感じ

		![スクリーンショット 2014-10-02 22.33.13.png](https://qiita-image-store.s3.amazonaws.com/0/35733/bc3e081c-7739-88ec-2657-ced39988602f.png "スクリーンショット 2014-10-02 22.33.13.png")

	- サンプルソース(Starter Kit)もダウンロードできる

		![スクリーンショット 2014-10-02 19.22.00.png](https://qiita-image-store.s3.amazonaws.com/0/35733/70002ba5-0ced-90b5-b954-d17d6f2348b5.png "スクリーンショット 2014-10-02 19.22.00.png") ![スクリーンショット 2014-10-02 19.23.12.png](https://qiita-image-store.s3.amazonaws.com/0/35733/ea6fc297-8b1e-2f2b-8a84-727dc6aa0c46.png "スクリーンショット 2014-10-02 19.23.12.png")

- Reactの本体ソース
	- [GitHub]https://github.com/facebook/react
	- お手軽に試すなら、CDN から読めばいいらしい。

		```html:
		<script src="http://fb.me/react-0.11.1.js"></script>
		<script src="http://fb.me/JSXTransformer-0.11.1.js"></script>
		```

		- CDNで利用できるリソースの一覧
			- http://cdnjs.com/libraries/react/

	- Bower でもインストールできるみたい。

		```shell:
		$ bower install --save react
		```

- エクステンション？も Facebookのチームが作っている
	- https://github.com/reactjs
	- **Rails 用の gem** もあった
- Reactに関するスライド（日本語）
	- [MVCはもう古い！？ React + Flux](http://www.slideshare.net/dsuket/react-js-368742470)
		- これは「天下一クライアントサイドJS MV*フレームワーク武道会」でのもの
	- [Get Started React.js](https://speakerdeck.com/koba04/get-started-react-dot-js)

## Yeoman で プロジェクトのテンプレを探してみた

手抜きでてっとり早く試してみようと思い、探してみたら誰かが作ったテンプレがあったので、２つ試してみた。ちなみに前提となる手元の環境はこちら⇒[MacでYeomanの環境を構築する手順](http://qiita.com/hkusu/items/0d2ed38c47b73201f4c2)

### ① generator-react-webpack

ジェネレータのソースはこれ⇒https://github.com/newtriks/generator-react-webpack

- ジェネレータをインストール

	```shell:
	$ npm install -g generator-react-webpack
	```

- ジェネレータを起動

	```shell:
	$ yo react-webpack
	```

	![スクリーンショット 2014-10-02 17.53.21.png](https://qiita-image-store.s3.amazonaws.com/0/35733/1cafa863-0ea1-cd30-a858-7a75ea45c06b.png "スクリーンショット 2014-10-02 17.53.21.png")

- 次のようにファイルが展開された

	![スクリーンショット 2014-10-02 18.15.00.png](https://qiita-image-store.s3.amazonaws.com/0/35733/78c5bdaf-e87f-e8bc-4de3-e7d70a67ff98.png "スクリーンショット 2014-10-02 18.15.00.png")

- 動作確認

	```shell:
	$ grunt serve
	```

	![スクリーンショット 2014-10-02 18.13.52.png](https://qiita-image-store.s3.amazonaws.com/0/35733/de78791a-fa68-a46f-67aa-4a4baaad91c7.png "スクリーンショット 2014-10-02 18.13.52.png")

- ちなみに配信用にビルドする場合は、

	```shell:
	$ grunt build
	```

ソース見てみたけど、なんかピンと来ず.. 次のジェネレータを試すことに。

### ② generator-react-gulp-browserify

ジェネレータのソースはこれ⇒https://github.com/randylien/generator-react-gulp-browserify

周辺環境として **Gulp** と **Browserify** を採用しているみたいですね。個人的には、こっちの方がいいかな。

- ジェネレータをインストール

	```shell:
	$ npm install -g generator-react-gulp-browserify
	```

- Gulp と SASS が必要らしいので、それぞれインストール

	```shell:
	$ npm install -g gulp
	```

	```shell:
	$ gem install sass
	```

	もしかして CoffeeScript が未インストールの場合は、いれておく必要があるかもしれません。

- ジェネレータを起動

	```shell:
	$ yo react-gulp-browserify
	```

	![スクリーンショット 2014-10-02 18.19.21.png](https://qiita-image-store.s3.amazonaws.com/0/35733/73f4e21b-2a25-7090-17d7-03055686ebb2.png "スクリーンショット 2014-10-02 18.19.21.png")

- 初期状態では Bower 管理下のライブラリ類が入ってない？みたいなので、インストール

	```shell:
	$ bower install
	```

- 最終的には、次のようにファイルが展開された

	![スクリーンショット 2014-10-02 18.34.14.png](https://qiita-image-store.s3.amazonaws.com/0/35733/14add330-2047-4621-ff04-5841c091a3c2.png "スクリーンショット 2014-10-02 18.34.14.png")

- 動作確認

	```shell:
	$ gulp watch
	```

	ブラウザで `http://localhost:9000` にアクセスしてみる。

	![スクリーンショット 2014-10-02 18.43.51.png](https://qiita-image-store.s3.amazonaws.com/0/35733/3805b129-632f-fdbf-0658-5272441ecedb.png "スクリーンショット 2014-10-02 18.43.51.png")

	やはり、こっちのジェネレータの方が分りやすそうですね。

- ソースをちょっと見てみる
	- どうやら `React.createClass()` にオブジェクトを渡してモジュールを作るみたい。そのオブジェクトの中の `render:` キーの値が、View に表示する内容みたいですね。

	```javascript:app/scripts/app.js
	/** @jsx React.DOM */
	
	var React = window.React = require('react'),
	    Timer = require("./ui/Timer"),
	    mountNode = document.getElementById("app");
	
	var TodoList = React.createClass({
	  render: function() {
	    var createItem = function(itemText) {
	      return <li>{itemText}</li>;
	    };
	    return <ul>{this.props.items.map(createItem)}</ul>;
	  }
	});
	var TodoApp = React.createClass({
	  getInitialState: function() {
	    return {items: [], text: ''};
	  },
	  onChange: function(e) {
	    this.setState({text: e.target.value});
	  },
	  handleSubmit: function(e) {
	    e.preventDefault();
	    var nextItems = this.state.items.concat([this.state.text]);
	    var nextText = '';
	    this.setState({items: nextItems, text: nextText});
	  },
	  render: function() {
	    return (
	      <div>
	        <h3>TODO</h3>
	        <TodoList items={this.state.items} />
	        <form onSubmit={this.handleSubmit}>
	          <input onChange={this.onChange} value={this.state.text} />
	          <button>{'Add #' + (this.state.items.length + 1)}</button>
	        </form>
	        <Timer />
	      </div>
	    );
	  }
	});
	
	
	React.renderComponent(<TodoApp />, mountNode);
	```

## おわりに

まだ評価できるほど触っていませんが、印象としてはわりと分りやすい構造なんじゃないかな、と思いました。もうすこしやってみようと思います。