モダンJavaScriptの基礎から始める挫折しないためのReact入門 60日コース | モダンJavaScript基礎 - DAY 6:map

React 60日で身につけるReact
スポンサーリンク
スポンサーリンク
  1. DAY 6:map 前半 ― 「配列を変換する」という発想を身につける
  2. map()とは何か ― 「配列を別の配列に変換する道具」
    1. 配列を“1対1で変換する”メソッド
  3. 基本構文とテンプレート ― Arrow Functionとセットで覚える
    1. map()の基本構文
    2. 例:数値を2倍にする
    3. 1行Arrow Functionとの組み合わせ(暗黙のreturn)
  4. 「配列を変換する」感覚を具体例でつかむ
    1. 例1:文字列を加工する(挨拶文を作る)
    2. 例2:数値を文字列に変換する
  5. 新しい配列が返ってくることの意味 ― 元の配列を壊さない
    1. 元の配列はそのまま残る
    2. セキュリティ・安全性の観点からも重要
  6. オブジェクト配列への入り口 ― 前半で軽く触れておく
    1. オブジェクト配列とは
    2. map()でオブジェクト配列を変換する
  7. DAY 6:map 前半のまとめ
  8. DAY 6:map 中盤 ― 「使いこなすための核心部分」
  9. 前半の復習から中盤への橋渡し
    1. 前半で押さえたmap()の基本
  10. Arrow Functionとの組み合わせを深掘りする
    1. 1行Arrow Functionはmap()と相性抜群
    2. テンプレートとして覚える形
  11. map()のコールバック引数を理解する(要素・インデックス・配列)
    1. 3つの引数が渡される
    2. インデックスを使った具体例
  12. オブジェクト配列をmap()で扱う ― 実務に近い形
    1. オブジェクト配列の基本形
    2. プロパティを取り出すmap()
    3. 複数のプロパティを使って文字列を作る
  13. オブジェクト配列を“そのまま”変換する ― 新しいオブジェクト配列を作る
    1. 価格に税込を反映した新しい配列を作る
  14. セキュリティ・安全性の視点から見たmap()とオブジェクト配列
    1. 「元のデータを壊さない」ことの意味
    2. Reactとの接続
  15. DAY 6:map 中盤のまとめ
  16. DAY 6:map 後半 ― Reactで「リスト表示」を支える主役としてのmap
  17. 前半・中盤の復習からReactへの橋渡し
    1. map()の本質的な役割
  18. Reactでの典型パターン:配列をmap()でJSXに変換する
    1. 商品一覧を表示するコンポーネントの例
  19. Arrow Function+map+オブジェクト配列の“型”を体に染み込ませる
    1. よく出てくる定番テンプレート
  20. keyの役割とインデックスの扱い(安全性の観点も含めて)
    1. keyとは何か
    2. インデックスをkeyに使う場合の注意点
  21. map()で“変換ロジック”を分離して読みやすくする
    1. 変換ロジックを別の関数に切り出す
    2. 「変換ロジックを関数として扱う」という発想
  22. セキュリティ・安全性の視点から見たmap+React
    1. 「入力 → 出力」が明確なコードは安全性が高い
    2. 外部からの入力をそのまま危険な処理に渡さない
  23. DAY 6:map 後半のまとめ
  24. DAY 6:map ミニ課題 ― 商品の価格に消費税を追加する
  25. オブジェクト配列で商品一覧を用意する
    1. 商品一覧の基本形を作る
  26. map()で「税込価格を追加した新しい配列」を作る
    1. 消費税率を決める
    2. map()+Arrow Functionで変換ロジックを書く
    3. 結果を確認する
  27. 1行Arrow Functionでさらにコンパクトに書く
    1. 暗黙のreturnを使った書き方
  28. Reactでの利用イメージ ― 税込価格を表示する
    1. JSXに変換する例
  29. セキュリティ・安全性の視点から見る「税込価格の追加」
    1. 元のデータを直接書き換えない理由
    2. map()で「入力と出力を分ける」ことの意味
  30. ミニ課題のまとめ ― mapで「現実的な処理」を組み立てる

DAY 6:map 前半 ― 「配列を変換する」という発想を身につける

DAY 6では、Reactでは必須級のメソッドである map() を扱います。 前半では、map()の「考え方」と「基本構文」、そして 配列を“変換して新しい配列を作る”という発想 を、Arrow Functionと組み合わせながら丁寧に解説していきます。

このDAY全体は、

  • 前半:map()とは/配列を変換する/新しい配列が返ってくる
  • 中盤:Arrow Functionとの組み合わせを深掘り/インデックス・オブジェクト配列
  • 後半:Reactの実践例(リスト表示)/セキュリティ・安全性の視点

という3回構成ですが、ここでは「前半」にフォーカスして説明します。

map()とは何か ― 「配列を別の配列に変換する道具」

配列を“1対1で変換する”メソッド

map()は、「ある配列から、対応する別の配列を作る」ためのメソッドです。

  • 元の配列:入力
  • map()の中で行う処理:変換ルール
  • 新しい配列:出力

というイメージで捉えると分かりやすいです。

まずはシンプルな例から見てみます。

const numbers = [1, 2, 3];

const doubled = numbers.map((n) => {
  return n * 2;
});

console.log(doubled);  // [2, 4, 6]
console.log(numbers);  // [1, 2, 3]
JavaScript

ここで起きていることをステップで整理すると、

  1. numbers[1, 2, 3] という配列です。
  2. numbers.map((n) => { return n * 2; }) を呼び出します。
  3. map()は、配列の各要素に対して順番に処理を行います。
    • 1 → n * 2 → 2
    • 2 → n * 2 → 4
    • 3 → n * 2 → 6
  4. 変換後の値を集めて、新しい配列 [2, 4, 6] を返します。
  5. 元の numbers は一切変更されません。

重要ポイント:

  • map()は「元の配列を変えずに、新しい配列を返す」メソッドです。
  • 「1つの要素 → 1つの新しい値」という 1対1の変換 を行います。

基本構文とテンプレート ― Arrow Functionとセットで覚える

map()の基本構文

map()の基本構文は次のようになります。

const 新しい配列 = 元の配列.map((要素) => {
  // 要素をどう変換するかを書く
  return 変換後の値;
});
JavaScript

このテンプレートに、具体的な処理を当てはめていきます。

例:数値を2倍にする

const numbers = [1, 2, 3, 4];

const doubled = numbers.map((n) => {
  return n * 2;
});

console.log(doubled);  // [2, 4, 6, 8]
JavaScript
  • n は「元の配列の1つの要素」を表します。
  • return n * 2; が「変換ルール」です。
  • map()は、すべての要素にこのルールを適用し、新しい配列を返します。

1行Arrow Functionとの組み合わせ(暗黙のreturn)

map()は、Arrow Functionと組み合わせて1行で書くことが非常に多いです。

const numbers = [1, 2, 3, 4];

const doubled = numbers.map((n) => n * 2);

console.log(doubled);  // [2, 4, 6, 8]
JavaScript
  • {} を省略し、return も省略しています。
  • n * 2 の結果」が暗黙的に戻り値になります。

Reactのコードでは、このような map()+1行Arrow Function」 の形が頻出します。 前半の段階では、「map()はArrow Functionとセットで使うことが多い」というイメージを持っておくと良いです。

「配列を変換する」感覚を具体例でつかむ

例1:文字列を加工する(挨拶文を作る)

const names = ['佐藤', '鈴木', '田中'];

const greetings = names.map((name) => {
  return `こんにちは、${name}さん!`;
});

console.log(greetings);
// ['こんにちは、佐藤さん!', 'こんにちは、鈴木さん!', 'こんにちは、田中さん!']
JavaScript

ここで起きていることは、

  • 元の配列:['佐藤', '鈴木', '田中']
  • 変換ルール:name を受け取り、挨拶文に変える
  • 新しい配列:挨拶文の一覧

という流れです。

ポイント:

  • 元の配列の「型」(ここでは文字列)から、別の「型」(挨拶文)に変換しています。
  • map()は「表示用のデータを作る」ときに非常に役立ちます。

例2:数値を文字列に変換する

const prices = [100, 200, 300];

const labels = prices.map((price) => {
  return `${price}円(税込)`;
});

console.log(labels);
// ['100円(税込)', '200円(税込)', '300円(税込)']
JavaScript
  • 元の配列:数値の一覧
  • 新しい配列:表示用の文字列一覧

Reactでは、「表示用のラベル」を作る場面が多いため、 このような「数値 → 文字列」の変換はよく使われます。

新しい配列が返ってくることの意味 ― 元の配列を壊さない

元の配列はそのまま残る

map()の重要な特徴は、元の配列を変更しないという点です。

const numbers = [1, 2, 3];

const doubled = numbers.map((n) => n * 2);

console.log(numbers); // [1, 2, 3]
console.log(doubled); // [2, 4, 6]
JavaScript
  • numbers は元のまま [1, 2, 3]
  • doubled は新しく作られた [2, 4, 6]

この「元の配列を壊さずに、新しい配列を作る」というスタイルは、 Reactの状態管理(state)と非常に相性が良いです。

セキュリティ・安全性の観点からも重要

元の配列を直接書き換えないことで、

  • 「どこで何が変更されているか」が分かりやすくなる
  • 意図しない副作用(他の変数も同じ配列を参照している場合など)を防ぎやすくなる
  • 状態の変化を追いやすくなり、バグや不正な挙動を減らせる

といったメリットがあります。

安全で予測可能なコードを書くうえで、 「元のデータを壊さず、新しいデータを作る」 という発想は非常に重要です。

オブジェクト配列への入り口 ― 前半で軽く触れておく

オブジェクト配列とは

Reactでは、「商品一覧」「ユーザー一覧」などを オブジェクトの配列 として扱うことが多いです。

const products = [
  { id: 1, name: 'Tシャツ', price: 1200 },
  { id: 2, name: 'ジーンズ', price: 4800 },
  { id: 3, name: 'スニーカー', price: 6800 },
];
JavaScript
  • 各要素が「1つの商品」を表すオブジェクト
  • 全体として「商品一覧」を表す配列

map()でオブジェクト配列を変換する

前半の段階では、シンプルな変換例だけ見ておきます。

const productNames = products.map((product) => {
  return product.name;
});

console.log(productNames);
// ['Tシャツ', 'ジーンズ', 'スニーカー']
JavaScript
  • 元の配列:商品オブジェクトの一覧
  • 変換ルール:product.name を取り出す
  • 新しい配列:商品名の一覧

Reactでは、このように「オブジェクト配列から特定のプロパティだけ取り出す」処理が頻繁に登場します。 中盤・後半では、ここからさらに一歩踏み込んで、 「オブジェクト配列をそのままJSXに変換する」パターンを扱っていきます。

DAY 6:map 前半のまとめ

前半では、

  • map()は「配列を別の配列に変換する」ためのメソッドであること
  • 基本構文:元の配列.map((要素) => { return 変換後の値; }); というテンプレートで書けること
  • Arrow Functionと組み合わせて1行で書く形((n) => n * 2)がReactで頻出すること
  • 元の配列を壊さずに、新しい配列が返ってくること
  • 文字列や数値を加工して「表示用のデータ」を作る場面でmap()が役立つこと
  • オブジェクト配列に対しても、map()で特定のプロパティを取り出せること

を確認しました。

この土台の上に、中盤では「Arrow Functionとの組み合わせをさらに深掘りし、インデックスやオブジェクト配列を本格的に扱う」 ことを、 後半では「Reactコンポーネント内でmap()を使ってリスト表示を行う実践的なパターン」 を学んでいくことで、 map()が「Reactでは必須級」と言われる理由が、自然と腑に落ちてくるはずです。


DAY 6:map 中盤 ― 「使いこなすための核心部分」

DAY 6の中盤では、前半で触れた map()の基本的な考え方 をさらに深掘りし、 特に重要な Arrow Functionとの組み合わせオブジェクト配列を扱うときのmap を、ステップバイステップで整理していきます。

Reactでは、map()とArrow Function、そしてオブジェクト配列の3つはほぼセットで登場します。 ここをしっかり押さえることで、Reactのコードが一気に読みやすく・書きやすくなっていきます。

前半の復習から中盤への橋渡し

前半で押さえたmap()の基本

前半では、次のようなポイントを確認しました。

const numbers = [1, 2, 3];

const doubled = numbers.map((n) => {
  return n * 2;
});

console.log(doubled);  // [2, 4, 6]
console.log(numbers);  // [1, 2, 3]
JavaScript
  • map()は「配列を別の配列に変換する」メソッドであること。
  • 元の配列は変更されず、新しい配列が返ってくること。
  • Arrow Functionと組み合わせて、(n) => n * 2 のように1行で書けること。

この土台の上に、中盤では 「どう書くと読みやすく・再利用しやすくなるか」 という視点で、 Arrow Functionとオブジェクト配列を扱っていきます。

Arrow Functionとの組み合わせを深掘りする

1行Arrow Functionはmap()と相性抜群

map()の中で使う関数は、Arrow Functionで書くのが圧倒的に多いです。 特に、1行で書くArrow Function(暗黙のreturn) は、Reactのコードで頻出します。

const numbers = [1, 2, 3, 4];

const doubled = numbers.map((n) => n * 2);

console.log(doubled); // [2, 4, 6, 8]
JavaScript

ここでは、

  • (n) => n * 2 がArrow Function
  • n * 2 の結果が暗黙的に戻り値として返される
  • map()がその結果を集めて、新しい配列を作る

という流れになっています。

テンプレートとして覚える形

よく使う形は、次のテンプレートとして覚えておくと便利です。

const 新しい配列 = 元の配列.map((要素) => 変換後の値);
JavaScript

具体例:

const names = ['佐藤', '鈴木', '田中'];

const greetings = names.map((name) => `こんにちは、${name}さん!`);

console.log(greetings);
// ['こんにちは、佐藤さん!', 'こんにちは、鈴木さん!', 'こんにちは、田中さん!']
JavaScript
  • name が「元の配列の1つの要素」
  • `こんにちは、${name}さん!` が「変換後の値」
  • map()がそれを集めて、新しい配列を返します。

この「テンプレート+具体例」の形で覚えておくと、 Reactのコードを読むときに「何をしているか」がすぐに見えてきます。

map()のコールバック引数を理解する(要素・インデックス・配列)

3つの引数が渡される

map()に渡す関数(Arrow Function)は、実は 3つの引数 を受け取ることができます。

const numbers = [10, 20, 30];

const result = numbers.map((value, index, array) => {
  console.log('value:', value);   // 要素
  console.log('index:', index);   // インデックス
  console.log('array:', array);   // 元の配列
  return value * 2;
});
JavaScript
  • 第1引数:要素(value) → 元の配列の1つ1つの値
  • 第2引数:インデックス(index) → その要素が何番目か(0から始まる番号)
  • 第3引数:配列(array) → 元の配列そのもの

通常は第1引数だけを使うことが多いですが、 インデックスを使うと「何番目か」に応じた処理が書けるようになります。

インデックスを使った具体例

const names = ['佐藤', '鈴木', '田中'];

const labeled = names.map((name, index) => {
  return `${index + 1}番目: ${name}`;
});

console.log(labeled);
// ['1番目: 佐藤', '2番目: 鈴木', '3番目: 田中']
JavaScript
  • index は0から始まるので、表示用には index + 1 として使っています。
  • 「何番目の要素か」をラベルに含めることができます。

Reactでは、map()の中で index を使って key を指定する場面もありますが、 それは後半で詳しく扱うテーマになります。

オブジェクト配列をmap()で扱う ― 実務に近い形

オブジェクト配列の基本形

Reactでは、「商品一覧」「ユーザー一覧」などを オブジェクトの配列 として扱うことが非常に多いです。

const products = [
  { id: 1, name: 'Tシャツ', price: 1200 },
  { id: 2, name: 'ジーンズ', price: 4800 },
  { id: 3, name: 'スニーカー', price: 6800 },
];
JavaScript
  • 各オブジェクトが「1つの商品」を表します。
  • 全体として「商品一覧」を表す配列です。

プロパティを取り出すmap()

まずは、オブジェクト配列から特定のプロパティだけを取り出す例を見てみます。

const productNames = products.map((product) => {
  return product.name;
});

console.log(productNames);
// ['Tシャツ', 'ジーンズ', 'スニーカー']
JavaScript
  • product が「1つの商品オブジェクト」
  • product.name が「商品名」
  • map()が商品名だけを集めて、新しい配列を作ります。

このパターンは、Reactで「一覧表示用のラベル」を作るときに非常によく使われます。

複数のプロパティを使って文字列を作る

const productLabels = products.map((product) => {
  return `${product.name}${product.price}円)`;
});

console.log(productLabels);
// ['Tシャツ(1200円)', 'ジーンズ(4800円)', 'スニーカー(6800円)']
JavaScript
  • product.nameproduct.price を組み合わせて表示用の文字列を作っています。
  • 「オブジェクト配列 → 表示用の文字列配列」という変換です。

Reactコンポーネント内では、このような「表示用のラベル」をそのままJSXに変換することが多く、 map()はその橋渡し役として機能します。

オブジェクト配列を“そのまま”変換する ― 新しいオブジェクト配列を作る

価格に税込を反映した新しい配列を作る

map()は、単にプロパティを取り出すだけでなく、 「オブジェクトを加工して、新しいオブジェクト配列を作る」 こともできます。

const taxRate = 0.1;

const productsWithTax = products.map((product) => {
  const taxIncludedPrice = Math.floor(product.price * (1 + taxRate));
  return {
    id: product.id,
    name: product.name,
    price: product.price,
    taxIncludedPrice: taxIncludedPrice,
  };
});

console.log(productsWithTax);
/*
[
  { id: 1, name: 'Tシャツ', price: 1200, taxIncludedPrice: 1320 },
  { id: 2, name: 'ジーンズ', price: 4800, taxIncludedPrice: 5280 },
  { id: 3, name: 'スニーカー', price: 6800, taxIncludedPrice: 7480 },
]
*/
JavaScript

ここで起きていることをステップで整理すると、

  1. products の各要素(商品オブジェクト)に対して、map()が順番に処理を行う。
  2. product.price に税込計算を行い、taxIncludedPrice を求める。
  3. 元の情報(id, name, price)に加えて、taxIncludedPrice を持つ新しいオブジェクトを返す。
  4. それらを集めて、新しい配列 productsWithTax が作られる。
  5. 元の products は一切変更されない。

重要ポイント:

  • map()は「オブジェクト → 別のオブジェクト」という変換もできる。
  • 元の配列を壊さずに、新しい配列を作ることで、安全で予測可能なコードになる。

セキュリティ・安全性の視点から見たmap()とオブジェクト配列

「元のデータを壊さない」ことの意味

オブジェクト配列を扱うときに、元の配列やオブジェクトを直接書き換えてしまうと、

  • どこで何が変更されたか分かりにくくなる
  • 他の処理が同じデータを参照している場合、意図しない影響が出る
  • 状態の変化を追いづらくなり、バグや不正な挙動の原因になる

といった問題が起きやすくなります。

map()で新しい配列を作るスタイルは、

  • 元の配列はそのまま保持される
  • 新しい配列にだけ変更を反映する
  • 「入力」と「出力」が明確に分かれる

という点で、安全で信頼性の高いコードにつながります。

Reactとの接続

Reactの状態管理(useStateなど)では、

  • 元の状態(配列)を直接書き換えず、
  • map()やスプレッド構文などを使って新しい配列を作り、
  • それを「新しい状態」としてセットする

というスタイルが基本になります。

中盤で学んだ「Arrow Function+map+オブジェクト配列」の組み合わせは、 このReactのスタイルに直結する重要な基礎です。

DAY 6:map 中盤のまとめ

中盤では、

  • map()に渡すArrow Functionが、要素・インデックス・配列の3つの引数を受け取れること
  • 1行Arrow Function((value) => value * 2)がmap()と非常に相性が良いこと
  • オブジェクト配列に対してmap()を使い、特定のプロパティだけを取り出せること
  • オブジェクトを加工して、新しいオブジェクト配列を作ることができること
  • 元の配列を壊さずに新しい配列を作ることが、安全で予測可能なコードにつながること
  • Reactの状態管理とmap()のスタイルが密接に関係していること

を確認しました。

この土台の上に、後半では 「Reactコンポーネント内でmap()を使ってリスト表示を行う実践的なパターン」 を扱い、 map()が「Reactでは必須級」と言われる理由を、実際のUIコードを通して体感していく流れになります。


DAY 6:map 後半 ― Reactで「リスト表示」を支える主役としてのmap

DAY 6の後半では、前半・中盤で学んだ map()/配列を変換する/新しい配列/Arrow Functionとの組み合わせ/オブジェクト配列 を、 いよいよ Reactの実際のコードの中でどう使うか という視点でまとめていきます。

ここまでの学びを「Reactのリスト表示」という具体的な形に落とし込むことで、 map()が「Reactでは必須級」と言われる理由が、実感としてつかめるようになるはずです。

前半・中盤の復習からReactへの橋渡し

map()の本質的な役割

前半・中盤を通して、map()について次のようなポイントを確認してきました。

  • 配列を別の配列に変換するメソッドであること
  • 元の配列を壊さずに、新しい配列を返すこと
  • Arrow Functionと組み合わせて、(value) => 変換後の値 という形で書くことが多いこと
  • オブジェクト配列に対して、特定のプロパティを取り出したり、新しいオブジェクト配列を作ったりできること

この「配列を変換して新しい配列を作る」という性質が、 Reactでは「配列 → JSX(UIの部品)」という変換にそのまま使われます。

Reactでの典型パターン:配列をmap()でJSXに変換する

商品一覧を表示するコンポーネントの例

まずは、シンプルな商品一覧を表示するReactコンポーネントを見てみます。

const products = [
  { id: 1, name: 'Tシャツ', price: 1200 },
  { id: 2, name: 'ジーンズ', price: 4800 },
  { id: 3, name: 'スニーカー', price: 6800 },
];

function ProductList() {
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>
          {product.name}{product.price}円)
        </li>
      ))}
    </ul>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. products は「商品オブジェクトの配列」です。
  2. products.map((product) => (...)) で、各商品オブジェクトをJSXに変換しています。
  3. product は「1つの商品」を表すオブジェクトです。
  4. return の代わりに、( ... )<li>...</li> を返しています(1行Arrow Function+暗黙のreturn)。
  5. map()がそれぞれの <li> を集めて、新しい配列(JSXの配列)を作ります。
  6. { ... } の中にその配列を埋め込むことで、<ul> の中に複数の <li> が並びます。

重要ポイント:

  • map()は「データの配列 → JSXの配列」という変換に使われています。
  • Arrow Functionで「1つのデータを1つのUI部品に変換する」ルールを書いています。
  • オブジェクト配列(products)が、そのままUIのリスト表示に直結しています。

Reactでは、このパターンがあまりにも頻繁に登場するため、 map()を理解しているかどうかが「リスト表示を書けるかどうか」に直結します。

Arrow Function+map+オブジェクト配列の“型”を体に染み込ませる

よく出てくる定番テンプレート

Reactのリスト表示で、ほぼ定番と言っていいテンプレートは次の形です。

{配列.map((item) => (
  <タグ key={item.id}>
    {/* itemから必要な情報を取り出して表示 */}
  </タグ>
))}
JSX

具体例として、ユーザー一覧を表示するコンポーネントを見てみます。

const users = [
  { id: 1, name: '佐藤', age: 28 },
  { id: 2, name: '鈴木', age: 34 },
  { id: 3, name: '田中', age: 22 },
];

function UserList() {
  return (
    <div>
      {users.map((user) => (
        <p key={user.id}>
          {user.name}{user.age}歳)
        </p>
      ))}
    </div>
  );
}
JSX

ここでは、

  • users がオブジェクト配列
  • user が「1人のユーザー」を表すオブジェクト
  • user.nameuser.age を使って表示内容を作っている
  • map()で「ユーザー → <p>タグ」という変換を行っている

という構造になっています。

この「配列 → JSX」の変換パターンを、 「定番テンプレート」として覚えてしまうのがおすすめです。

keyの役割とインデックスの扱い(安全性の観点も含めて)

keyとは何か

Reactでは、map()でリストを表示するときに、 key という属性を指定することが推奨されています。

{products.map((product) => (
  <li key={product.id}>
    {product.name}{product.price}円)
  </li>
))}
JSX

key は、Reactが「どの要素がどれか」を識別するための 一意なID のようなものです。

  • リストの並びが変わったとき
  • 要素が追加・削除されたとき

などに、Reactが効率よく差分を計算するために使われます。

インデックスをkeyに使う場合の注意点

id がない場合、インデックスを key に使うこともできます。

{names.map((name, index) => (
  <li key={index}>{name}</li>
))}
JSX

ただし、インデックスを key に使うと、

  • 要素の並びが変わったとき
  • 要素の途中に追加・削除が入ったとき

に、Reactが「同じインデックスの別の要素」を同一視してしまい、 意図しない挙動が起きる可能性があります。

そのため、可能であれば一意なID(idなど)をkeyに使うほうが安全です。

これは、UIの整合性や予測可能性という意味で、 セキュリティ・安全性の広い文脈にもつながる考え方です。

map()で“変換ロジック”を分離して読みやすくする

変換ロジックを別の関数に切り出す

map()の中身が複雑になってきたら、 Arrow Functionをその場で書くのではなく、別の関数に切り出すと読みやすくなります。

const products = [
  { id: 1, name: 'Tシャツ', price: 1200 },
  { id: 2, name: 'ジーンズ', price: 4800 },
  { id: 3, name: 'スニーカー', price: 6800 },
];

function renderProduct(product) {
  return (
    <li key={product.id}>
      {product.name}{product.price}円)
    </li>
  );
}

function ProductList() {
  return <ul>{products.map(renderProduct)}</ul>;
}
JSX

ここでは、

  • renderProduct という関数が「1つの商品 → <li>」という変換ルールを担当しています。
  • map(renderProduct) で、そのルールをすべての商品に適用しています。

このように、map()の中で行う処理を関数として分離すると、

  • ロジックの再利用がしやすくなる
  • テストしやすくなる
  • コードの見通しが良くなる

といったメリットがあります。

「変換ロジックを関数として扱う」という発想

これは、DAY 4で学んだ Arrow Functionを変数に保存する/関数を部品として扱う という考え方ともつながっています。

  • map()に渡す関数は、「変換ロジック」という部品
  • その部品を別の場所に切り出しておくことで、コードが整理される

という構造を意識すると、 Reactのコンポーネント設計が一段階クリアになる感覚が得られるはずです。

セキュリティ・安全性の視点から見たmap+React

「入力 → 出力」が明確なコードは安全性が高い

map()を使って「配列 → JSX」を変換するスタイルは、

  • 入力:配列(データ)
  • 変換ルール:Arrow Function(表示ロジック)
  • 出力:JSX(UI)

という流れが非常に明確です。

このような構造は、

  • どこで何が行われているかが分かりやすい
  • データの変更と表示の変更の関係が追いやすい
  • 意図しない副作用が起きにくい

という意味で、安全で予測可能なコードにつながります。

外部からの入力をそのまま危険な処理に渡さない

map()で外部からの入力(APIレスポンスなど)を扱う場合でも、

  • 必要なプロパティだけを取り出す
  • 不要な情報や危険な情報(HTML文字列など)をそのまま表示しない
  • サニタイズ(無害化)やバリデーション(検証)を挟む

といった工夫をすることで、 UIの安全性やセキュリティを高めることができます。

map()はあくまで「変換の道具」なので、 「何をどう変換するか」を設計する側の意識が重要になります。

DAY 6:map 後半のまとめ

後半では、

  • map()がReactで「配列 → JSX」の変換に使われる主役であること
  • 商品一覧やユーザー一覧などのオブジェクト配列を、map()+Arrow Functionでリスト表示に変換できること
  • key 属性が、Reactにとって「リスト要素を識別するための一意なID」として重要であること
  • インデックスをkeyに使う場合の注意点と、一意なIDを使うことの安全性
  • 変換ロジックを別の関数に切り出すことで、コードの再利用性・可読性・テストしやすさが向上すること
  • 「入力 → 変換 → 出力」が明確なmap()のスタイルが、安全で予測可能なReactコードにつながること

を確認しました。

DAY 4(Arrow Function)、DAY 5(配列)、DAY 6(map)を通して、 モダンJavaScriptとReactの「基礎の三本柱」がかなり揃ってきています。

この先のステップでは、filterreduce などのメソッドも組み合わせながら、 より複雑なデータ変換やUIロジックを、 「宣言的で読みやすいコード」 として書いていく世界へ進んでいくことになります。


DAY 6:map ミニ課題 ― 商品の価格に消費税を追加する

このミニ課題では、map()/配列を変換する/新しい配列/Arrow Functionとの組み合わせ/オブジェクト配列 を使って、 「商品の価格に消費税を追加する」という、実務でもよくある処理をステップバイステップで作っていきます。

ゴールは、

  • 元の商品一覧(オブジェクト配列)を壊さずに
  • 税込価格を含んだ新しい商品一覧を作る

という形を、自然に書けるようになることです。

オブジェクト配列で商品一覧を用意する

商品一覧の基本形を作る

まずは、商品一覧をオブジェクト配列で表現します。 ここでは、idnameprice(税抜価格)を持つシンプルな構造にします。

const products = [
  { id: 1, name: 'Tシャツ', price: 1200 },
  { id: 2, name: 'ジーンズ', price: 4800 },
  { id: 3, name: 'スニーカー', price: 6800 },
];
JavaScript
  • 各オブジェクトが「1つの商品」を表します。
  • 全体として「商品一覧」を表す配列です。
  • price は「税抜価格」として扱います。

この「オブジェクト配列」という形が、Reactでも非常によく使われるデータ構造です。

map()で「税込価格を追加した新しい配列」を作る

消費税率を決める

まず、消費税率を変数として定義します。 ここでは例として10%(0.1)とします。

const taxRate = 0.1;
JavaScript
  • taxRate は「税率」を表す数値です。
  • price * (1 + taxRate) で税込価格を計算できます。

map()+Arrow Functionで変換ロジックを書く

次に、map()を使って「税込価格を追加した新しい商品一覧」を作ります。

const productsWithTax = products.map((product) => {
  const taxIncludedPrice = Math.floor(product.price * (1 + taxRate));
  return {
    id: product.id,
    name: product.name,
    price: product.price,
    taxIncludedPrice: taxIncludedPrice,
  };
});
JavaScript

ここで起きていることを、丁寧にステップで追っていきます。

  1. products.map((product) => { ... }) を呼び出します。
  2. map()は、products の各要素(商品オブジェクト)に対して順番に処理を行います。
  3. product には、1つ目・2つ目・3つ目の商品オブジェクトが順番に渡されます。
  4. product.price * (1 + taxRate) で税込価格を計算します。
    • 例:1200 * 1.1 = 1320
  5. Math.floor(...) で小数点以下を切り捨てて、整数の価格にします。
  6. return { ... } で、新しいオブジェクトを返します。
    • 元の idnameprice をそのままコピー
    • 新しく taxIncludedPrice プロパティを追加
  7. map()がそれぞれの新しいオブジェクトを集めて、productsWithTax という新しい配列を作ります。

結果を確認する

console.log(productsWithTax);
/*
[
  { id: 1, name: 'Tシャツ', price: 1200, taxIncludedPrice: 1320 },
  { id: 2, name: 'ジーンズ', price: 4800, taxIncludedPrice: 5280 },
  { id: 3, name: 'スニーカー', price: 6800, taxIncludedPrice: 7480 },
]
*/
JavaScript
  • 各商品に taxIncludedPrice が追加されています。
  • 元の products は変更されていません。
console.log(products);
/*
[
  { id: 1, name: 'Tシャツ', price: 1200 },
  { id: 2, name: 'ジーンズ', price: 4800 },
  { id: 3, name: 'スニーカー', price: 6800 },
]
*/
JavaScript

重要ポイント:

  • map()は「元の配列を壊さずに、新しい配列を返す」メソッドです。
  • 安全で予測可能なコードを書くうえで、この性質は非常に重要です。

1行Arrow Functionでさらにコンパクトに書く

暗黙のreturnを使った書き方

慣れてきたら、Arrow Functionを1行で書く形にしてもよいです。

const productsWithTax = products.map((product) => ({
  id: product.id,
  name: product.name,
  price: product.price,
  taxIncludedPrice: Math.floor(product.price * (1 + taxRate)),
}));
JavaScript

ここでは、

  • { ... } を丸括弧 (...) で囲むことで、「オブジェクトを返す1行Arrow Function」にしています。
  • return を省略し、暗黙のreturnを使っています。

Reactのコードでは、このような map()+1行Arrow Function+オブジェクト配列」 の形が頻繁に登場します。 ミニ課題の段階でこの形に触れておくと、後のステップで違和感なく読めるようになります。

Reactでの利用イメージ ― 税込価格を表示する

JSXに変換する例

作成した productsWithTax を、Reactコンポーネントで表示するイメージも見ておきます。

function ProductListWithTax() {
  const taxRate = 0.1;

  const products = [
    { id: 1, name: 'Tシャツ', price: 1200 },
    { id: 2, name: 'ジーンズ', price: 4800 },
    { id: 3, name: 'スニーカー', price: 6800 },
  ];

  const productsWithTax = products.map((product) => ({
    id: product.id,
    name: product.name,
    price: product.price,
    taxIncludedPrice: Math.floor(product.price * (1 + taxRate)),
  }));

  return (
    <ul>
      {productsWithTax.map((product) => (
        <li key={product.id}>
          {product.name}:税抜 {product.price}円/税込 {product.taxIncludedPrice}
        </li>
      ))}
    </ul>
  );
}
JSX

ここでは、

  • 1つ目のmap()で「商品オブジェクト → 税込価格付きの商品オブジェクト」に変換
  • 2つ目のmap()で「商品オブジェクト → <li>(JSX)」に変換

という 二段階の変換 を行っています。

ポイント:

  • map()は「データ → 別のデータ」にも、「データ → JSX」にも使える汎用的な道具です。
  • Arrow Functionとオブジェクト配列を組み合わせることで、処理の流れが非常に明確になります。

セキュリティ・安全性の視点から見る「税込価格の追加」

元のデータを直接書き換えない理由

もし、元の products を直接書き換えてしまうと、 他の処理が同じ配列を参照している場合に、意図しない影響が出ることがあります。

const products = [
  { id: 1, name: 'Tシャツ', price: 1200 },
  { id: 2, name: 'ジーンズ', price: 4800 },
];

products.forEach((product) => {
  product.taxIncludedPrice = Math.floor(product.price * (1 + taxRate));
});
JavaScript

このように直接プロパティを追加すると、

  • どこで何が変更されたか分かりにくくなる
  • 他のコードが「税抜価格だけのはず」と思って使っていると、想定外の状態になる
  • 状態の変化を追いづらくなり、バグや不正な挙動の原因になる

といった問題が起きやすくなります。

map()で「入力と出力を分ける」ことの意味

map()で新しい配列を作るスタイルは、

  • 入力:元の配列(税抜価格だけの商品一覧)
  • 変換:税込価格を計算して、新しいオブジェクトを作る
  • 出力:税込価格付きの商品一覧

という流れが明確です。

このように「入力」と「出力」を分けることで、

  • どの処理が何をしているかが追いやすくなる
  • 意図しない共有や副作用を防ぎやすくなる
  • 安全で予測可能なコードにつながる

というメリットがあります。

ミニ課題のまとめ ― mapで「現実的な処理」を組み立てる

このミニ課題では、

  • 商品一覧をオブジェクト配列として用意する
  • taxRate を使って税込価格を計算する
  • map()+Arrow Functionで「税込価格付きの新しい商品一覧」を作る
  • 元の配列を壊さずに、新しい配列を返すというmap()の性質を確認する
  • Reactコンポーネント内で「データ → JSX」の変換にmap()を使うイメージを持つ
  • セキュリティ・安全性の観点からも、「入力と出力を分ける」スタイルが重要であることを意識する

という流れを通して、map()が単なる「便利メソッド」ではなく、 現実的なビジネスロジック(価格計算など)とReactのUI表示をつなぐ重要な基礎ツール であることを確認しました。

この感覚を持ったまま、次のステップで filterreduce なども組み合わせていくと、 より複雑なデータ変換や集計処理を、 「読みやすく・安全で・Reactと相性の良いコード」として書けるようになっていきます。

タイトルとURLをコピーしました