React入門 03: JSON形式の配列から複数データを取り出してページに表示する
Tags: javascript, webdev, tutorial, react
Published: 2020-01-15 10:14:51

---
title: React入門 03: JSON形式の配列から複数データを取り出してページに表示する
published: true
description: ページに表示するデータは、サーバーなどから得ることが多いでしょう。その場合、JSON形式が扱いやすく、APIから返すデータなどにもよく使われています。今回は、変数に納めた配列から取り出したデータを、コンポーネントのテキストとして表示してみます。
tags: #javascript, #webdev, #tutorial, #react
---

ページに表示するデータは、サーバーなどから得ることが多いでしょう。その場合、JSON形式が扱いやすく、APIから返すデータなどにもよく使われています。今回は、データのやり取りは置いておき、変数に納めた配列から取り出したデータを、コンポーネントのテキストとして表示してみます。手を加えるのは、「React入門 02: ライブラリMarkedでMarkdownの機能を加える」で書いたアプリケーションのモジュールです。

# 配列にまとめたJSONデータを子コンポーネントに渡す
データのテキストはJSONのかたちにして、大もとのコンポーネント(`src/App.js`)のクラス(`App`)のプロパティ(`data`)として、つぎのように配列要素として納めます。その値は、テンプレートの子コンポーネント(`CommentList`)のタグに同名の属性(`data`)として与えましょう。これで、子コンポーネントはプロパティから値が参照できます。

```react
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()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map)メソッドでJSXテンプレートから要素をつくって変数(`commentNodes`)に配列で納めます。これを波かっこ`{}`に入れてテンプレートに加えれば、配列の要素すべてが差し込まれる仕組みです(「[複数のコンポーネントをレンダリングする](https://ja.reactjs.org/docs/lists-and-keys.html#rendering-multiple-components)」)[^1]。これで、配列要素のデータが取り出されてページに表示できます(図001)。

なお、要素には一意の値を[`key`属性](https://ja.reactjs.org/docs/lists-and-keys.html#keys)として与えなければなりません。Reactが要素の変更を`key`にもとづいて識別するためです。


```react
// 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データが取り出されて子コンポーネントに表示される
![02_004.png](https://thepracticaldev.s3.amazonaws.com/i/955pp236dwlpbcp5xsom.png)

書き改めたコンポーネントふたつのJavaScriptコード全体は、つぎのとおりです(コード001および002)。

#### コード001■`src/components/CommentList.js`
```react
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`
```react
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;
```


[^1]: Vue.jsではテンプレートに特別な属性(ディレクティブ)[`v-for`](https://jp.vuejs.org/v2/api/#v-for)を加えることで、データの数だけテンプレートがつくられて差し込まれます(「Vue.js入門 03: データから動的にリストをつくる」01「[項目のデータを複数にする](http://www.fumiononaka.com/Business/html5/FN1702006.html#sec01)」参照)。つまり、JavaScriptコードでテンプレートをつくる必要はありません。<br><br>Angularも、ほぼ同じ構文のディレクティブ[`*ngFor`](https://angular.io/guide/template-syntax#ngFor)を備えています(「Display a Heroes List」「[List heroes with *ngFor](https://angular.io/tutorial/toh-pt2#list-heroes-with-ngfor)」参照)。