19
17

More than 5 years have passed since last update.

React.jsチュートリアルをやる(2)

Posted at

React.jsチュートリアルをやる(1)のつづき。

サーバからデータを取得する

ルートコンポーネントから渡していくデータの取得先をサーバに変える。

ReactDOM.render(
- <CommentBox data={data} />,
+ <CommentBox url="/api/comments" />,
  document.getElementById('content')
);

この時点ではまだ動かない。サーバからデータを取得したタイミングで、コンポーネントを更新する必要がある。

コンポーネントの読み込みの基本形は<CommentBox />。読み込むコンポーネントにデータを渡したい場合は<CommentBox data={data} />のように書く。読み込まれたコンポーネント内でthis.props.dataのように書くことで、このデータにアクセスできる。
上のコードでは<CommentBox url="/api/comments" />としてるので、CommentBoxコンポーネント内でthis.props.urlと書くことでurlを取得することができる。

Reactive state

(1)で親コンポーネントから子コンポーネントへのデータの引き渡しにpropsを使ったが、propsはイミュータブルのため、親から受け継いだ値の変更ができない。親と子でインタラクティブにデータのやり取りをするためにはpropsではなくstateを使う。

var CommentBox = React.createClass({
+ getInitialState: function() {
+   return {data: []};
+ },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
-       <CommentList data={this.props.data} />
+       <CommentList data={this.state.data} />
        <CommentForm />
      </div>
    );
  }
});

CommentListへのデータの受け渡しを{this.props.data}から<CommentList data={this.state.data}に変更した。こうすることで、サーバからデータを取得したタイミングでthis.setState()を使いCommentListコンポーネントを更新することができる。

またgetInitialState()はコンポーネントのライフサイクルにおいて最初の一度だけ実行され、初期値を設定することができる。

stateの更新

コンポーネント作成時にjsonデータをサーバから取得し、データを最新のものに更新してみる。今回jsonデータ取得はajaxで行う。

var CommentBox = React.createClass({
+ loadCommentsFromServer: function() {
+   $.ajax({
+     url: this.props.url,
+     dataType: 'json',
+     cache: false,
+     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>
    );
  }
});

ReactDOM.render(
- <CommentBox url="/api/comments" />,
+ <CommentBox url="/api/comments" pollInterval={2000} />,
  document.getElementById('content')
);

componentDidMount()はコンポーネントが最初にレンダリングされた際に実行されるReactのメソッド。中で独自メソッドのthis.loadCommentsFromServerを呼び出し、データをサーバから取得している。

上のコードの処理の流れは、たぶんこんな感じ。
1. ReactDom.render()でフレームワーク起動、CommentBoxコンポーネントのレンダリング
2. getInitialState()statedata値設定。これはrender内でthis.state.dataと書くことでアクセス可能。
3. componentDidMount()が実行され、サーバからajaxでデータを取得。
4. データが取得できたらthis.setState({data: data});が実行され、statedataプロパティにajaxで取得したデータが挿入され、コンポーネントが再びレンダリング。

実行

ここまで書けばとりあえず動かせるようになるようなので、動かしてみる。
サーバはなんでもいい。自分はnodeサーバを起動。

$ node server.js
Server started: http://localhost:3000/

ブラウザでhttp://localhost:3000/にアクセス。

Hello_React.png

/comments.jsonを更新。

[
    {
        "id": 1388534400000,
        "author": "Pete Hunt",
        "text": "Hey there!"
    },
    {
        "id": 1420070400000,
        "author": "Paul O’Shannessy",
        "text": "React is *great*!"
    }
]

[
    {
        "id": 1388534400000,
        "author": "Pete Hunt",
        "text": "Hey there!"
    },
    {
        "id": 1420070400000,
        "author": "Paul O’Shannessy",
        "text": "React is *great*!"
    },
    {
        "id": 9999999999999,
        "author": "ABCDEFG",
        "text": "あいうえお"
    }
]

Hello_React.png

リアルタイムで更新された。

(2)おしまい。(3)に続く。

19
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
17