2016/9/17 関連記事情報を追加しました。
本章ではReactでのstate管理について説明します。
ただ、state管理については、現在reduxの使用がメジャーとなっているようで、
Reactでstate管理する場面は少ないのかもしれません。
- immutableとmutable
まず言葉の定義から。
-
immutable(イミュータブル)
作成後にその状態を変えることができないオブジェクトを指します。
4章までで作成したサンプルでは、1度しかレンダリングが行われないように作成されているため、イミュータブルなアプリといえます。 -
mutable(ミュータブル)
作成後でも状態の変更が可能なオブジェクトを指します。
本章で作成するアプリは、更新を検知するようにし、自身を再びレンダリングするように作成するため、ミュータブルなアプリといえます。
- state管理
今回は、別サーバ上のPHPで作成されたAPIをAjaxでたたき、取得したデータをReactでstate管理・レンダリングするような構成となります。画面表示結果は4章までと変わりありません。
/*global $*/
import React from "react";
import ReactDOM from "react-dom";
var UserBox = React.createClass({
render: function(){
return(
<div classNmae="userBox">
<ul>
<li>No: {this.props.no}</li>
<li>Name: {this.props.name}</li>
<li>Message: {this.props.message}</li>
<li>Age: {this.props.age}</li>
</ul>
</div>
);
}
});
var UserData = React.createClass({
loadUserData: function(){
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data){
this.setState({
data: data
});
}.bind(this)
});
},
getInitialState: function(){
return {data: []};
},
componentWillMount: function(){
this.loadUserData();
setInterval(this.loadUserData, this.props.pollInterval);
},
render: function(){
var usermap = this.state.data.map(function(user) {
var age = 25;
var key = user.no;
return (
<UserBox no={user.no} name={user.name} message={user.message} age={age} key={key} />
);
});
return (
<div className="userData">
{usermap}
</div>
);
}
});
ReactDOM.render(
<UserData url="https://your-api-project.c9users.io/server.php" pollInterval={1000} />,
document.getElementById('content')
);
getInitialState
はコンポーネントライフサイクルで一度だけ呼び出され、stateの初期値を設定します。ここでは、data
を初期化しているような形となります。
componentWillMount
はコンポーネントがDOMツリーに追加される前に一度だけ呼びだされます。ここでは、this.loadUserData()
(※AjaxでAPIをたたく処理)と、setInterval
(※1000ミリ秒毎にthis.loadUserData()
を呼び出す処理)が実行されています。
componentWillMount
で2回this.loadUserData()
が呼ばれているように見えますが、setInterval
内のthis.loadUserData()
は、初回レンダリングまでに1000ミリ秒かかってしまうため、setInterval
の外で一度this.loadUserData()
を呼んでやる必要があります。
余談ですが、ReactにはAngular2のhttpモジュールのようなAjax機能は存在しないため、何かしら用意してやる必要性があります。この例ではjqueryを使用しています。
(上記のような色々と欠けている機能を補完しないといけないところが、Reactの設計が大変だと言われる一端かもしれないですね。)
- テスト用API
2節でReact側の実装は完了しましたが、これだけでは本章のアプリは動作しません。https://your-api-project.c9users.io/server.php
を別サーバで実装する必要があります。(別に同じサーバでもいいんですけどね、、)
まず、Cloud9のページにアクセスし、自身のアカウントでログインする。次に「Create a new workspace」をクリックします。
作成画面では、下記の例のように好みのWorkspace名を記載します。今回は他機能からAPIをたたく必要があるため、「Public」を選択しておいてください。また、APIはPHPで作成するので、「PHP」を選択しておいてください。
WorkSpaceが立ちあがったら、「api-project」配下にserver.phpを作成し、中に下記コードを記載します。
<?php
$value = array(
array('no'=> 1, 'name' => "Taro", 'message' => "Hello"),
array('no'=> 2, 'name' => "Jiro", 'message' => "Good Bye"),
array('no'=> 3, 'name' => "Kumi", 'message' => "Thank you"),
);
header("Content-Type: application/json; charset=UTF-8");
header("X-Content-Type-Options: nosniff");
header("Access-Control-Allow-Origin: *");
echo json_encode(
$value,
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
);
コードを保存したら、server.php > Run でApacheを起動します。
Apache起動後に下記のように表示が出るので、表示されたURLをapp.jsのrender
内のurl
に記載してください。
Starting Apache httpd, serving https://your-api-project.c9users.io/server.php.
Started apache2
- 確認
ここまで完了したら、react-studyのindex.htmlをRunして、表示を確認してください。下図のように表示されていたら成功です。
最後にミュータブルになっているか確認してみましょう。api-projectのserver.phpのjson項目を書き換えてみてください。
ページリロードをしていないにもかかわらず、index.htmlの表示が自動で変わっていることが確認できます。
- 引用
チュートリアル | React
https://facebook.github.io/react/docs/tutorial-ja-JP.html
React.jsのComponent Lifecycle
http://qiita.com/koba04/items/66e9c5be8f2e31f28461
- 関連記事
cloud9環境でReactの検証① -導入-
cloud9環境でReactの検証② -コンポーネント-
cloud9環境でReactの検証③ -変数の扱い-
cloud9環境でReactの検証④ -ループ-