こんにちは、白々さじきです。
今回は、Reactでリスト(配列のデータ)をJSXに表示するときの書き方についてまとめます。
JavaScriptを学んできた人は「ループは for 文で書く」という感覚があると思います。Reactでも最初は for 文を書こうとして、うまくいかないことがあります。
結論
JSXの中では for 文は使えません。.map() を使います。また、繰り返しで生成した要素には必ず key prop を付けます。
なぜ for 文が使えないのか
JSXの {} の中に書けるのは「式(expression)」だけです。for 文は「文(statement)」なので書けません。
| 種類 | 例 | JSXの中で使えるか |
|---|---|---|
| 式 | list.map(...), condition ? A : B | 使える |
| 文 | for (...), if (...) {} | 使えない |
.map() は配列を別の配列に変換して返す「式」なので、JSXの中に書けます。
type Shop = { id: string; name: string };
// NG: JSXの中にfor文は書けない
const ShopList = ({ shops }: { shops: Shop[] }) => {
return (
<ul>
{for (const shop of shops) { // SyntaxError
<li>{shop.name}</li>
}}
</ul>
);
};
// OK: .map() を使う
const ShopList = ({ shops }: { shops: Shop[] }) => {
return (
<ul>
{shops.map((shop) => (
<li key={shop.id}>{shop.name}</li>
))}
</ul>
);
};
.map() の書き方
.map() は配列の各要素に関数を適用して、新しい配列を返します。
// shops の各要素に対して <li> を返す → <li> の配列ができる
shops.map((shop) => (
<li key={shop.id}>{shop.name}</li>
))
JSXを複数行に書くときは () で囲みます。
// 1行のとき
shops.map((shop) => <li key={shop.id}>{shop.name}</li>)
// 複数行のとき(カッコで囲む)
shops.map((shop) => (
<li key={shop.id}>
<span>{shop.name}</span>
<span>{shop.address}</span>
</li>
))
key prop が必要な理由
.map() で生成した要素には key を付けないと警告が出ます。
Warning: Each child in a list should have a unique "key" prop.
Reactはリストが更新されたとき(要素の追加・削除・並び替え)に、どの要素が変わったかを識別する必要があります。key はその識別子として使われます。
// NG: key がない
shops.map((shop) => <li>{shop.name}</li>)
// NG: インデックスを key にする(並び替え時に不具合が起きやすい)
shops.map((shop, i) => <li key={i}>{shop.name}</li>)
// OK: ユニークなIDを key にする
shops.map((shop) => <li key={shop.id}>{shop.name}</li>)
key にはリスト内で一意な値を使います。データに id フィールドがある場合はそれが最適です。
Google Maps でマーカーを複数表示する例
地図系のコンポーネントでも同じパターンを使います。地図は1つで、マーカーだけ .map() で複数生成します。
// NG: 地図ごと複数作ってしまう
{shops.map((shop) => (
<Map>
<AdvancedMarker position={shop.position} />
</Map>
))}
// OK: 地図は1つ、マーカーだけ .map()
<Map defaultCenter={center} defaultZoom={12}>
{shops.map((shop) => (
<AdvancedMarker key={shop.id} position={shop.position} />
))}
</Map>
まとめ
- JSXの
{}の中には「式」しか書けないためfor文は使えない .map()は配列を返す「式」なのでJSXの中で使える.map()で生成した要素には一意なkeyprop を付けるkeyにはインデックスではなくデータのidを使う
最初は「なんで for 文が書けないんだろう」と思いましたが、JSXが「式の世界」だと理解してからはすっきりしました。
参考リンク
サポートのお願い
下記リンクからお買い物いただけると、ブログ運営のための費用が増え、有料サービスを利用した記事作成が可能になります。ご協力よろしくお願いします!

コメント