サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

React入門 04: JSONデータをローカルサーバーから読み込んでページに表示する


JSONファイルをローカルサーバーに置いて、そのデータを読み込み、ページに動的に表示します。本稿では、ローカルサーバーはReactのチュートリアルのファイルを用いて立ち上げます。その設定にもとづいてJSONデータを読み込みますので、「React入門 03: データはJSON形式にしてページをローカルサーバーで表示する」をまだお読みでない方は02「チュートリアルのサンプルファイルとNode.jsのインストール」を ご参照ください。

01 ローカルサーバーからJSONデータを読み込む準備

これから、「React入門 03: データはJSON形式にしてページをローカルサーバーで表示する」で書いたコード001「JSONデータにまとめたMarkdownのテキストをHTMLのコードに変えて差し込む」に手を加えます。まずは、JSONデータをローカルサーバーのファイルから受け取るため、つぎのように変数(data)はコメントアウトし、コンポーネント(CommentBox)のプロパティ(url)にJSONファイルのパスを与えます。なお、このパス("/api/comments")は、前述のとおりチュートリアルのファイル(server.js)の定めにもとづいています。


/* var data = [
	{id: 1, author: "ヘンリー・キッシンジャー", text: "チャンスは__貯金__できない。"},
	{id: 2, author: "マーク・トウェイン", text: "禁煙なんてたやすい。私は*何千回*もやった。"}
]; */

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

親コンポーネントのプロパティ値は、propsで受け取ることができました。けれど、このプロパティは親子の間のやりとりで中身を書き替えることができません。互いにデータを変えたいときに用いるのが、stateプロパティです。このプロパティに含めるデータは、つぎのようにgetInitialState()メソッドで初期値を定めます。JSONファイルから読み込むデータ(data)は、初めは空([])でよいでしょう。子コンポーネント(CommentList)からは、this.stateを参照してデータが取り出せます(「React Without ES6」の「Setting the Initial State」参照)。


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

02 ファイルの配置とローカルサーバーの立ち上げ

前述のとおり、チュートリアルの設定にしたがってファイルを配置し、ローカルサーバーでHTMLドキュメントを開きます。コマンドラインツールでチュートリアルのファイル(server.js)があるフォルダ(ディレクトリ)に入り、つぎのコマンドでローカルサーバーが立ち上がります(前掲「チュートリアルのサンプルファイルとNode.jsのインストール」参照)。publicフォルダがローカルサーバーのルート(http://localhost:3000/)になりますので、その中にHTMLドキュメント(sample.html)とJavaScriptファイル(src/script.js)を入れてください(図001)。


node server.js

図001■チュートリアルのファイルに置いたpublicフォルダの中にHTMLドキュメントとJavaScriptファイルを納める

図001

そして、変数に入れていたつぎのJSONデータの配列は外部ファイル(comments.json)にして、チュートリアルのファイルと同じ場所(publicフォルダと同階層)に保存します(前掲図001参照)。


[
    {
        "id": 1388534400000,
        "author": "ヘンリー・キッシンジャー",
        "text": "チャンスは__貯金__できない。"
    },
    {
        "id": 1420070400000,
        "author": "マーク・トウェイン",
        "text": "禁煙なんてたやすい。私は*何千回*もやった。"
    }
]

03 JSONデータをAJAXで読み込んでページに表示する

AJAXを使ったJSONデータの読み込みは、Reactの役目ではありません。ここでは、jQueryを用います。HTMLドキュメント(sample.html)に<script>要素で、つぎのようにCDNから読み込むことにします。


<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample</title>
<script src="https://unpkg.com/react@15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.23.1/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="src/script.js" type="text/babel"></script>
</head>
<body>
	<div id="content"></div>
</body>
</html>

JSONデータは、コンポーネントがページに差し込まれ、Reactから階層内をすべて参照できるようになったら読み込みます。この初期化が済んだとき一度だけ呼び出されるのがcomponentDidMount()メソッドです。この関数本体で、jQueryのjQuery.ajax()メソッドにより、つぎのようにJSONデータを読み込みます。引数には設定のプロパティが定められたオブジェクトを渡します(「$.ajax()」参照)。用いたプロパティについては、以下の表001にまとめました。stateを変えるには、ReactのsetState()メソッドを呼び出し、新たなデータをオブジェクトにして引数として渡します。


var CommentBox = React.createClass({
	getInitialState: function() { /* [中略] */ },
	componentDidMount: function() {
		$.ajax({
			url: this.props.url,
			dataType: 'json',
			cache: false,
			success: function(data) {
				this.setState({data: data});
			}.bind(this),
			error: function(xhr, status, error) {
				console.error(this.props.url, status, error.toString());
			}.bind(this)
		});
	},
	render: function() { /* [中略] */ }
});

表001■jQuery.ajax()メソッドに渡した引数のオブジェクトに定めたプロパティ

jQuery.ajax()メソッドの引数に与えられるプロパティ
url リクエストの送り先URLを示す文字列。
dataType サーバーから返されるデータのタイプを示す文字列。つぎの種類がある。
  • xml
  • html
  • script
  • json
  • jsonp
  • text
cache falseを与えると、リクエストされたページをブラウザにキャッシュさせない。デフォルト値はtrue
success リクエストが成功したときに呼び出す関数。第1引数にはdataTypeにもとづいてフォーマットされたデータが渡される。
error リクエストが失敗したときに呼び出す関数。第1引数にXMLHttpRequest(jqXHR)オブジェクト、第2引数にはエラーの種類を示す文字列、第3引数にHTTPステータスのテキスト部分が渡される。

これでコンポーネントがページに描かれるとき、ローカルサーバーのJSONデータが読み込まれて、各要素に加えられます(図002)。以下のコード001に、書き上げたJavaScriptをまとめました。また、図002にサイトjsdo.itのコードをリンクしました(外部ファイルの読み込みが含まれるためページに埋め込めません)。

図002■ページが表示されるとともにJSONデータが差し込まれる

図002
>> jsdo.itのサンプルへ

コード001■ローカルサーバーから読み込んだJSONデータをHTMLページに差し込む


var CommentBox = React.createClass({
	getInitialState: function() {
		return {data: []};
	},
	componentDidMount: function() {
		$.ajax({
			url: this.props.url,
			dataType: 'json',
			cache: false,
			success: function(data) {
				this.setState({data: data});
			}.bind(this),
			error: function(xhr, status, error) {
				console.error(this.props.url, status, error.toString());
			}.bind(this)
		});
	},
	render: function() {
		return (
			<div className="commentBox">
				<h1>コメント</h1>
				<CommentList data={this.state.data} />
				<CommentForm />
			</div>
		);
	}
});
var CommentList = React.createClass({
	render: function() {
		var commentNodes = this.props.data.map(function(comment) {
			return (
				<Comment author={comment.author} key={comment.id}>
				{comment.text}
				</Comment>
			);
		});
		return (
			<div className="commentList">
			{commentNodes}
			</div>
		);
	}
});
var Comment = React.createClass({
	rawMarkup: function() {
		var markDown = new Remarkable();
		var rawMarkup = markDown.render(this.props.children.toString());
		return { __html: rawMarkup };
	},
	render: function() {
		return (
			<div className="comment">
				<h2 className="commentAuthor">
				{this.props.author}
				</h2>
				<span dangerouslySetInnerHTML={this.rawMarkup()} />
			</div>
		);
	}
});
var CommentForm = React.createClass({
	render: function() {
		return (
			<div className="commentForm">
				CommentFormを表示
			</div>
		);
	}
});
ReactDOM.render(
	<CommentBox url="/api/comments" />,
	document.getElementById('content')
);


作成者: 野中文雄
更新日: 2017年3月13日 ライブラリのバージョン更新にともなう修正。
更新日: 2016年8月30日 末尾のリンクにReact入門 06を追加
更新日: 2016年8月21日 末尾にReact入門シリーズのリンクを追加。
作成日: 2016年8月17日


Copyright © 2001-2017 Fumio Nonaka.  All rights reserved.