ページに表示するデータは、サーバーなどから得ることが多いでしょう。その場合、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.