React.jsのTutorialを試してみる(2


前回のつづきでReact.jsのTutorialを試していきます。
前回までがうまくいってれば以下の画面のはず。

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')
      );

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

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

Reactive state

ここでstateなる概念がでてきます。statethis.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を設定するために1回だけ呼ばれます。この状態で画面を表示すると次のようになります。コメントが空の状態です。

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が可能になっています。ためしに画面を開いてください。以下のように2コメントが表示されるはずです。

この状態でcommets.jsonファイルを変更してみてください。2~3秒で反映されるはずです。

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