React.jsのTutorialを試してみる（２

[前回](http://qiita.com/kazusa-qooq/items/cec6359ea6423346cb24)のつづきでReact.jsのTutorialを試していきます。
前回までがうまくいってれば以下の画面のはず。

![image](https://qiita-image-store.s3.amazonaws.com/0/71988/13cc7cfc-d35c-67c3-3445-fc34a9b52ac7.png)

##Hook up the data model
前回はCommentに直書きでしたが、DataをJSONで渡すようです。最終的にはサーバから受け取りますが、ここではJSONをハードコーディングします。

まずdataを定義して最上位のコンポーネントであるBoxに渡します。

```
      var data = [
        {author: "Pete Hunt", text: "This is one comment"},
        {author: "Jordan Walke", text: "This is *another* comment"}
      ];
      React.render(
        <CommentBox data={data} />,
        document.getElementById('content')
      );
```

つぎに受け取ったデータをBoxがListに渡します。

```
      var CommentBox = React.createClass({
        render: function() {
          return (
            <div className="commentBox">
              <h1>Comments</h1>
              <CommentList data={this.props.data} />
              <CommentForm />
            </div>
          );
        }
      });
```

最後にListが受け取ったデータを使ってCommentを生成します。

```
      var CommentList = React.createClass({
        render: function() {
          var commentNodes = 
                this.props.data.map(function (comment) {
            return (
              <Comment author={comment.author}>
                {comment.text}
              </Comment>
            );
          });
          return (
            <div className="commentList">
              {commentNodes}
            </div>
          );
        }
      });
```

表示画面は先ほどと同じです。表示されない場合は、

```
      React.render(
        <CommentBox data={data} />,
        document.getElementById('content')
      );
```
よりあとにコンポーネント定義がないか確認してください。前回は先頭と書きましたが、正確にはこれより前に定義がないと動作しないようです。

##Fetching from the server
dataをviewから分離できたところでサーバーのお出ましです。ハードコードしたdataを削除し、`React.render`をつぎのように変更します。
注）この段階ではまだ機能しません

```
      React.render(
        <CommentBox url="comments.json" />,
        document.getElementById('content')
      );
```

ここで重要な点は２つです。

* コメントがあるたびに再描画する必要がある
* サーバからレスポンスがあるまでデータをもたない

##Reactive state
ここで`state`なる概念がでてきます。`state`は`this.setState()`によって変更され、その際に再描画が実行されます。ではCommentBoxにstateを定義します。

```
      var CommentBox = React.createClass({
        getInitialState: function() {
          return {data: []};
        },
        render: function() {
          return (
            <div className="commentBox">
              <h1>Comments</h1>
              <CommentList data={this.state.data} />
              <CommentForm />
            </div>
          );
        }
      });
```
`getInitialState`は初期stateを設定するために１回だけ呼ばれます。この状態で画面を表示すると次のようになります。コメントが空の状態です。
![image](https://qiita-image-store.s3.amazonaws.com/0/71988/31827d47-5fcd-e644-c572-bedff2c2a945.png)

##Updating state
サーバから情報をとってくるにあたりまずは静的ファイルを代用します。index.htmlと同位置に以下のファイルを作成しブラウザからアクセスできるか確認してください。

``` comments.json
[
  {"author": "Pete Hunt", "text": "This is one comment"},
  {"author": "Jordan Walke", "text": "This is *another* comment"}
]
```

このデータをajaxで取得します。CommentBoxをさらに変更します。

```
      var CommentBox = React.createClass({
        loadCommentsFromServer: function() {
          $.ajax({
            url: this.props.url,
            dataType: 'json',
            success: function(data) {
              this.setState({data: data});
            }.bind(this),
            error: function(xhr, status, err) {
              console.error(this.props.url, status, err.toString());
            }.bind(this)
          });
        },
        getInitialState: function() {
          return {data: []};
        },
        componentDidMount: function() {
          this.loadCommentsFromServer();
          setInterval(this.loadCommentsFromServer, this.props.pollInterval);
        },
        render: function() {
          return (
            <div className="commentBox">
              <h1>Comments</h1>
              <CommentList data={this.state.data} />
              <CommentForm />
            </div>
          );
        }
      });
      
      React.render(
        <CommentBox url="comments.json" pollInterval={2000} />,
        document.getElementById('content')
      );

```
ここで重要なのは`componentDidMount`メソッドです。このメソッドはレンダリング時に自動的に一度だけ実行されます。`loadCommentsFromServer`を呼び出し、stateを変更することで再描画が実行されます。
また`loadCommentsFromServer`をsetIntervalで繰り返し呼び出すことでLive Updateが可能になっています。ためしに画面を開いてください。以下のように２コメントが表示されるはずです。
![image](https://qiita-image-store.s3.amazonaws.com/0/71988/64182482-eb98-8044-85e3-7dc8c738be67.png)
この状態でcommets.jsonファイルを変更してみてください。２～３秒で反映されるはずです。

切りがいいので一端ここで締めます。
続きはまた次回。