前回からの続きですが、このページだけ読んでも分かる内容になっています。 今回読むReact公式ドキュメントは「リストと key」ページの前半です。
今回は、Reactで配列データをリストとしてレンダリングする方法を見ていきます。例えば、配列に入ったメニュー項目をli要素として描画するなど、使用頻度の高い書き方です。
JavaScriptのmap()関数で配列データを操作
Reactでリスト表示をする場合、一般的には配列を利用します。以下のコードでは、JavaScriptのmap()関数を使って配列データを操作しています。
// 配列データ
const numbers = [1, 2, 3, 4, 5];
/*
JavaScriptのmap()関数を使って配列numbersを操作したものを
配列listItemsとして格納
*/
const listItems = numbers.map((number) =>
<li>{number}</li>
);
// DOMへレンダリング
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
上記のサンプルソースをHTMLファイルにしたものが以下です。
https://programming-world.net/sample/react_doc/lists1-1.html
上記コードでは、 JavaScriptのmap()関数 を使って元の配列 numbers を操作したものを、新しい配列 listItems として格納しています。配列 listItems は、<li>~</li>で整数を囲んだものとなります。
そして、DOMへレンダリングする際に、<ul>~</ul>で配列 listItems を囲んだものを要素として出力しています。Reactでは、中括弧 {} で囲むことで、JSXのなかに任意の式を埋め込むことができますが、配列もそのまま埋め込めます。
JavaScriptのmap()関数について
ここで、JavaScriptのmap()関数について確認しておきましょう。 JavaScriptのmap()関数は、配列データを操作する際に使用するメソッドです。配列の各要素に対して何らかの処理をした結果を、新しい配列として返します。
以下のコードでは、map()関数を使用して、配列 numbers の各要素の値を 2 倍にした結果を、新しい配列 doubled に格納しています。
//元の配列 numbers
const numbers = [1, 2, 3, 4, 5];
//map()関数による操作結果を、新しい配列 doubled に格納
const doubled = numbers.map(
//配列の各要素を2倍にする
function(number) {
return number * 2;
}
);
//コンソールに [2, 4, 6, 8, 10] と出力されるはず
console.log(doubled);
上記コードを実行すると、コンソールに [2, 4, 6, 8, 10] と出力されます。
上記のコードは、アロー関数を使って書くこともできます。以下のコードは、上記コードと等価です。
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(
(number) => number * 2
);
console.log(doubled);
配列を受け取って要素のリストを出力するコンポーネントを作る
配列を受け取って要素のリストを出力するコンポーネントを作ってみましょう。
作りたいのは、[1, 2, 3, 4, 5]という内容の配列データをpropsで受け取って、<ul>や<li>タグで囲まれた要素のリストを返すコンポーネントです。
// NumberListコンポーネント
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
// 配列データ
const numbers = [1, 2, 3, 4, 5];
// レンダリング
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
上記のサンプルソースをHTMLファイルにしたものが以下です。
https://programming-world.net/sample/react_doc/lists1-2.html
このコードを実行すると、期待した結果が表示されるのですが、コンソールを確認してみると、何やら警告が出ているようです。以下は、Chromeのデベロッパー ツールでコンソールに表示される警告内容です。
警告:リスト内の各子には、一意の "key" プロップが必要です。 NumberList の render メソッドを確認してください。
警告を読んでみると、「NumberList コンポーネントで生成されるli要素には、一意の”key”が必要です」と言っているようです。
ちなみに、 Chromeのデベロッパー ツールでコンソール は、Chrome画面左上の [︙] アイコン → [その他のツール] → [デベロッパー ツール] で表示されます。
Reactが要素を識別するための“key”
さて、警告には「NumberList コンポーネントで生成されるli要素には、一意の”key”が必要です」とありますが、 “key” とは一体なんでしょうか?
結論を言えば、 “key” とは 、どの要素が追加・変更・削除されたのかを React が識別するためのものです。Reactでは、配列データからリストなどの要素を生成する場合、Reactが識別できるように生成される各要素に一意の key を割り当てる必要があります。
上のコードで言えば、生成されるそれぞれのli要素にkeyを割り当ててやる必要があります。以下は、keyを割り当てた例です。
// NumberListコンポーネント(各li要素にkeyを割り当て)
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
// 配列データ
const numbers = [1, 2, 3, 4, 5];
// レンダリング
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
上記のサンプルソースをHTMLファイルにしたものが以下です。
https://programming-world.net/sample/react_doc/lists1-3.html
今度は、コンソールに警告は出ていません。
まとめ
今回は、 Reactで配列データをリスト描画する方法について解説しました。
リスト項目として生成される要素には、Reactが識別できるようにそれぞれにkeyを割り当てる必要がありますが、次回は key についてもう少し詳しく解説します。
次回へ続きます。