ページに表示するデータは、サーバーなどから得ることが多いでしょう。その場合、JSON形式が扱いやすく、APIから返すデータなどにもよく使われています。今回は、データのやり取りは置いておき、変数に納めた配列から取り出したデータを、コンポーネントのテキストとして表示してみます。手を加えるのは、「React入門 02: ライブラリMarkedでMarkdownの機能を加える」で書いたアプリケーションのモジュールです。
配列にまとめたJSONデータを子コンポーネントに渡す
データのテキストはJSONのかたちにして、大もとのコンポーネント(src/App.js)のクラス(App)のプロパティ(data)として、つぎのように配列要素として納めます。その値は、テンプレートの子コンポーネント(CommentList)のタグに同名の属性(data)として与えましょう。これで、子コンポーネントはプロパティから値が参照できます。
function App() {
const data = [
{author: "ヘンリー・キッシンジャー", text: "チャンスは__貯金__できない。"},
{author: "マーク・トウェイン", text: "禁煙なんてたやすい。私は*何千回*もやった。"}
];
return (
<div className="App">
<h1>コメント</h1>
{/* <CommentList /> */}
<CommentList data={data} />
</div>
);
}
複数データからテンプレートをつくる
子コンポーネント(src/components/CommentList.js)が親から引数オブジェクトに受け取るプロパティ(data)は配列です。配列要素すべてをコンポーネントに表示するには、その数だけテンプレートが必要になります。
そこで、関数コンポーネントの中で、以下に抜き書きしたコードのようにArray.prototype.map()メソッドでJSXテンプレートから要素をつくって変数(commentNodes)に配列で納めます。これを波かっこ{}に入れてテンプレートに加えれば、配列の要素すべてが差し込まれる仕組みです(「複数のコンポーネントをレンダリングする」)1。これで、配列要素のデータが取り出されてページに表示できます(図001)。
なお、要素には一意の値をkey属性として与えなければなりません。Reactが要素の変更をkeyにもとづいて識別するためです。
// const CommentList = () => {
const CommentList = (props) => {
const commentNodes = props.data.map((comment, id) => (
<Comment author={comment.author} key={id}>
{comment.text}
</Comment>
));
return (
<div className="CommentList">
{/* <Comment author="ヘンリー・キッシンジャー">
チャンスは__貯金__できない。
</Comment>
<Comment author="マーク・トウェイン">
禁煙なんてたやすい。私は*何千回*もやった。
</Comment> */}
{commentNodes}
</div>
);
};
図001■配列のJSONデータが取り出されて子コンポーネントに表示される
書き改めたコンポーネントふたつのJavaScriptコード全体は、つぎのとおりです(コード001および002)。
コード001■src/components/CommentList.js
import React from 'react';
import Comment from './Comment';
const CommentList = (props) => {
const commentNodes = props.data.map((comment, id) => (
<Comment author={comment.author} key={id}>
{comment.text}
</Comment>
));
return (
<div className="CommentList">
{commentNodes}
</div>
);
};
export default CommentList;
コード002■src/App.js
import React from 'react';
import CommentList from './components/CommentList';
import CommentForm from './components/CommentForm';
import './App.css';
function App() {
const data = [
{author: "ヘンリー・キッシンジャー", text: "チャンスは__貯金__できない。"},
{author: "マーク・トウェイン", text: "禁煙なんてたやすい。私は*何千回*もやった。"}
];
return (
<div className="App">
<h1>コメント</h1>
<CommentList data={data} />
<CommentForm />
</div>
);
}
export default App;
-
Vue.jsではテンプレートに特別な属性(ディレクティブ)
v-forを加えることで、データの数だけテンプレートがつくられて差し込まれます(「Vue.js入門 03: データから動的にリストをつくる」01「項目のデータを複数にする」参照)。つまり、JavaScriptコードでテンプレートをつくる必要はありません。
Angularも、ほぼ同じ構文のディレクティブ*ngForを備えています(「Display a Heroes List」「List heroes with *ngFor」参照)。 ↩

Top comments (1)
Still waiting on my ff guaranteed 10x character drop.