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

React 60日で身につけるReact
スポンサーリンク
スポンサーリンク
  1. DAY 10:JavaScript総合演習 前半 ― 「商品データ管理」でここまでの基礎を一気につなげる
  2. データ構造と基本関数を決める ― 「土台づくり」の時間
    1. 商品データをどう表現するか ― オブジェクト配列で考える
    2. 関数で「機能」を分けて考える
  3. 検索と価格変更 ― filterとmapを組み合わせる
    1. 商品検索 ― filterで絞り込む
    2. 価格変更 ― map+Spread構文で「一部だけ更新」
  4. 商品追加・削除 ― Spread構文とfilterで「増やす・減らす」を作る
    1. 商品追加 ― Spread構文で「末尾に追加」
    2. 商品削除 ― filterで「条件に合わないものを除く」
  5. DAY 10:JavaScript総合演習 前半のまとめ
  6. DAY 10:JavaScript総合演習 中盤 ― 「機能をまとめて1つのプログラムにする」
  7. 機能を1つの「管理オブジェクト」にまとめる
    1. まずは「関数をバラバラに持っている状態」を確認する
    2. 管理用オブジェクトを作る ― 「商品Manager」という考え方
  8. 実際に「商品管理プログラム」として呼び出してみる
    1. 一連の操作をシナリオとして書いてみる
  9. Reactで使うイメージと安全性の視点を重ねる
    1. Reactコンポーネントから呼び出すイメージ
    2. セキュリティ・安全性の視点から見た「商品管理」
  10. DAY 10:JavaScript総合演習 中盤のまとめ
  11. DAY 10:JavaScript総合演習 後半 ― 「商品データ管理」を通して基礎を“実務レベル”に近づける
  12. 完成形を意識した「設計」と「役割分担」を整理する
    1. 商品データの基本構造をもう一度確認する
    2. 機能を「関数」として分ける理由
  13. 各機能を“安全な状態更新”として組み立てる
    1. 商品一覧 ― 配列をそのまま表示する関数
    2. 商品検索 ― filter()で絞り込み
    3. 価格変更 ― map()+Spread構文で「一部だけ更新」
    4. 商品追加 ― Spread構文で「配列コピー+末尾追加」
    5. 商品削除 ― filter()で「残したいものだけ残す」
  14. 機能を「連続したシナリオ」として実行し、Reactとのつながりを意識する
    1. 一連の流れをコードで実行する
    2. Reactで使うとどうなるか?という視点
    3. セキュリティ・安全性の観点から見たこの設計
  15. DAY 10:JavaScript総合演習 後半のまとめ

DAY 10:JavaScript総合演習 前半 ― 「商品データ管理」でここまでの基礎を一気につなげる

DAY 10では、ここまで学んできた

  • 関数
  • 配列
  • map
  • filter
  • オブジェクト
  • Spread構文

をすべて組み合わせて、商品データ管理プログラムを作っていきます。 前半では、次の機能を題材にしながら、土台となる考え方とコードの型を固めていきます。

  • 商品一覧
  • 商品検索
  • 価格変更
  • 商品追加
  • 商品削除

理解しやすいように「前半・中盤・後半」の3つに分けて、連続した流れとして説明していきます。

データ構造と基本関数を決める ― 「土台づくり」の時間

商品データをどう表現するか ― オブジェクト配列で考える

まずは、「商品データ」をどう表現するかを決めます。 ここまでの学習を活かすなら、オブジェクト配列が自然です。

const products = [
  { id: 1, name: 'Tシャツ', price: 1200, stock: 10 },
  { id: 2, name: 'ジーンズ', price: 4800, stock: 5 },
  { id: 3, name: 'スニーカー', price: 6800, stock: 3 },
];
JavaScript
  • { ... } が「1つの商品」を表すオブジェクトです。
  • 全体として products が「商品一覧」を表す配列です。
  • id は「識別子」で、検索や変更・削除のときに使います。

重要ポイント:

  • 「1つのもの」→オブジェクト
  • 「複数のもの」→オブジェクト配列
  • Reactでもこの形がそのまま使われます。

関数で「機能」を分けて考える

次に、機能ごとに関数を分けて考えます。

  • 商品一覧 → listProducts
  • 商品検索 → searchProducts
  • 価格変更 → changePrice
  • 商品追加 → addProduct
  • 商品削除 → deleteProduct

まずは「一覧表示」から始めます。

function listProducts(products) {
  products.forEach((product) => {
    console.log(
      `ID: ${product.id}, 商品名: ${product.name}, 価格: ${product.price}円, 在庫: ${product.stock}`
    );
  });
}

listProducts(products);
JavaScript

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

  1. listProductsは「商品一覧を表示する」関数です。
  2. 引数productsにオブジェクト配列を受け取ります。
  3. forEachで1件ずつ取り出し、console.logで表示しています。

重要ポイント:

  • 「機能ごとに関数を分ける」ことで、コードの見通しが良くなります。
  • Reactコンポーネントでも、「役割ごとに分ける」考え方がそのまま活きます。

検索と価格変更 ― filterとmapを組み合わせる

商品検索 ― filterで絞り込む

次に、「商品検索」を作ります。 ここでは、商品名にキーワードが含まれているものを絞り込む例を考えます。

function searchProducts(products, keyword) {
  const result = products.filter((product) => {
    return product.name.includes(keyword);
  });

  return result;
}

const found = searchProducts(products, 'ジーンズ');
listProducts(found);
JavaScript

ステップで整理すると、

  1. searchProductsは「商品一覧から条件に合うものだけを取り出す」関数です。
  2. products.filter(...)で、
    • productについてproduct.name.includes(keyword)を評価します。
    • trueになった商品だけが新しい配列resultに残ります。
  3. resultを返すことで、「検索結果の一覧」を別の配列として扱えます。

重要ポイント:

  • filterは「絞り込み」のための関数です。
  • 元のproductsは変更されず、「新しい配列」が返されます。
  • Reactでも、検索機能や絞り込み表示でこのパターンが頻出します。

価格変更 ― map+Spread構文で「一部だけ更新」

次に、「特定の商品だけ価格を変更する」機能を作ります。 ここでは、idで商品を特定し、その商品のpriceだけを変更します。

function changePrice(products, id, newPrice) {
  const updatedProducts = products.map((product) => {
    if (product.id === id) {
      return {
        ...product,
        price: newPrice,
      };
    } else {
      return product;
    }
  });

  return updatedProducts;
}

const productsAfterPriceChange = changePrice(products, 2, 5000);
listProducts(productsAfterPriceChange);
JavaScript

ステップで整理すると、

  1. changePriceは「特定の商品だけ価格を変更した新しい一覧を返す」関数です。
  2. products.map((product) => { ... })で、各商品を1件ずつ処理します。
  3. product.id === idのときだけ、
    • { ...product, price: newPrice }で「価格だけ変えた新しいオブジェクト」を作ります。
  4. それ以外の商品は、元のproductをそのまま返します。
  5. mapの結果として、「1件だけ価格が変わった新しい配列updatedProducts」ができます。

重要ポイント:

  • 「オブジェクト配列の一部だけを更新する」定番パターンは、
    • map+条件分岐+Spread構文(コピー+一部更新) です。
  • 元のproductsは直接書き換えず、「新しい配列」を返すことが安全で予測可能なコードにつながります。

商品追加・削除 ― Spread構文とfilterで「増やす・減らす」を作る

商品追加 ― Spread構文で「末尾に追加」

次に、「商品追加」を作ります。 新しい商品オブジェクトを受け取り、一覧の末尾に追加した新しい配列を返します。

function addProduct(products, newProduct) {
  const updatedProducts = [...products, newProduct];
  return updatedProducts;
}

const newProduct = {
  id: 4,
  name: 'キャップ',
  price: 3200,
  stock: 7,
};

const productsAfterAdd = addProduct(products, newProduct);
listProducts(productsAfterAdd);
JavaScript

ステップで整理すると、

  1. addProductは「新しい商品を追加した一覧を返す」関数です。
  2. const updatedProducts = [...products, newProduct];で、
    • 元のproductsの中身をコピーし、
    • 末尾にnewProductを追加した新しい配列を作っています。
  3. 元のproductsはそのまま残り、「追加後の一覧」を別の配列として扱えます。

重要ポイント:

  • Spread構文は「配列コピー+追加」のための定番パターンです。
  • ReactのState更新でも、この形が頻繁に登場します。

商品削除 ― filterで「条件に合わないものを除く」

最後に、「商品削除」を作ります。 ここでは、idが一致する商品を一覧から取り除く例を考えます。

function deleteProduct(products, id) {
  const updatedProducts = products.filter((product) => {
    return product.id !== id;
  });

  return updatedProducts;
}

const productsAfterDelete = deleteProduct(products, 2);
listProducts(productsAfterDelete);
JavaScript

ステップで整理すると、

  1. deleteProductは「特定の商品を除いた新しい一覧を返す」関数です。
  2. products.filter((product) => product.id !== id)で、
    • idが一致しない商品だけを残します。
    • 一致する商品は「除外」されます。
  3. 結果として、「削除後の一覧」が新しい配列として得られます。

重要ポイント:

  • filterは「残したいものだけを残す」関数ですが、
    • 条件を逆に書くことで「削除したいものを除外する」こともできます。
  • 元のproductsは変更されず、「削除後の一覧」を別の配列として扱えます。

DAY 10:JavaScript総合演習 前半のまとめ

DAY 10の前半では、

  • 商品データを「オブジェクト配列」で表現すること
  • 機能ごとに関数を分けて、「商品一覧」「商品検索」「価格変更」「商品追加」「商品削除」を設計したこと
  • filterで「検索」や「削除」を実現できること
  • map+Spread構文で「特定の商品だけ価格を変更する」パターンを確認したこと
  • Spread構文で「配列コピー+追加」を簡潔に書けること
  • すべての機能が「元の配列・オブジェクトを直接書き換えず、新しい配列・オブジェクトを返す」スタイルになっていること

を整理しました。

中盤・後半では、

  • これらの関数をまとめて「1つの商品管理モジュール」として扱う流れ
  • 実際にReactコンポーネントから呼び出すイメージ
  • セキュリティ・安全性の観点から「状態更新の設計」をどう考えるか

などを通して、 ここまでのJavaScript基礎が「Reactで挫折しないための武器」としてつながっていく形を、さらに具体的にしていきます。


DAY 10:JavaScript総合演習 中盤 ― 「機能をまとめて1つのプログラムにする」

DAY 10の中盤では、前半で作った

  • 商品一覧
  • 商品検索
  • 価格変更
  • 商品追加
  • 商品削除

のそれぞれの機能を、1つの「商品データ管理プログラム」としてまとめて扱う流れを作っていきます。 ここでも「前半・中盤・後半」に分けて、連続したストーリーとして説明していきます。

機能を1つの「管理オブジェクト」にまとめる

まずは「関数をバラバラに持っている状態」を確認する

前半で作った関数は、だいたいこんな形でした。

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

function listProducts(products) {
  products.forEach((product) => {
    console.log(
      `ID: ${product.id}, 商品名: ${product.name}, 価格: ${product.price}円, 在庫: ${product.stock}`
    );
  });
}

function searchProducts(products, keyword) {
  return products.filter((product) => product.name.includes(keyword));
}

function changePrice(products, id, newPrice) {
  return products.map((product) =>
    product.id === id
      ? { ...product, price: newPrice }
      : product
  );
}

function addProduct(products, newProduct) {
  return [...products, newProduct];
}

function deleteProduct(products, id) {
  return products.filter((product) => product.id !== id);
}
JavaScript

このままでも十分使えますが、 「商品管理」という1つのまとまりとして扱いたいので、 オブジェクトにまとめるという発想を使ってみます。

管理用オブジェクトを作る ― 「商品Manager」という考え方

次のように、「商品管理用のオブジェクト」を作ることができます。

const productManager = {
  list(products) {
    products.forEach((product) => {
      console.log(
        `ID: ${product.id}, 商品名: ${product.name}, 価格: ${product.price}円, 在庫: ${product.stock}`
      );
    });
  },

  search(products, keyword) {
    return products.filter((product) =>
      product.name.includes(keyword)
    );
  },

  changePrice(products, id, newPrice) {
    return products.map((product) =>
      product.id === id
        ? { ...product, price: newPrice }
        : product
    );
  },

  add(products, newProduct) {
    return [...products, newProduct];
  },

  delete(products, id) {
    return products.filter((product) => product.id !== id);
  },
};
JavaScript

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

  1. productManagerというオブジェクトを作っています。
  2. その中に、
    • list
    • search
    • changePrice
    • add
    • delete という「機能ごとのメソッド(関数)」をまとめています。
  3. それぞれのメソッドは、前半で作った関数とほぼ同じ処理を持っています。

重要ポイント:

  • 「機能をオブジェクトにまとめる」ことで、
    • productManager.list(products)
    • productManager.search(products, keyword) のように、「何をしているか」が一目で分かる呼び出し方になります。
  • Reactでも、「ロジックを1つのモジュールにまとめる」発想はそのまま活きます。

実際に「商品管理プログラム」として呼び出してみる

一連の操作をシナリオとして書いてみる

次に、このproductManagerを使って、 「商品一覧 → 検索 → 価格変更 → 追加 → 削除」という一連の流れをコードで書いてみます。

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

// 1. 商品一覧
console.log('--- 商品一覧 ---');
productManager.list(products);

// 2. 商品検索(「ジーンズ」を含む商品)
console.log('--- 商品検索(キーワード: ジーンズ) ---');
const found = productManager.search(products, 'ジーンズ');
productManager.list(found);

// 3. 価格変更(ID: 2 の商品を 5000円に変更)
console.log('--- 価格変更(ID: 2 → 5000円) ---');
products = productManager.changePrice(products, 2, 5000);
productManager.list(products);

// 4. 商品追加
console.log('--- 商品追加(キャップ) ---');
const newProduct = {
  id: 4,
  name: 'キャップ',
  price: 3200,
  stock: 7,
};
products = productManager.add(products, newProduct);
productManager.list(products);

// 5. 商品削除(ID: 1 の商品を削除)
console.log('--- 商品削除(ID: 1) ---');
products = productManager.delete(products, 1);
productManager.list(products);
JavaScript

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

  1. productsletで宣言し、「現在の商品一覧」として扱っています。
  2. 各操作のたびに、
    • products = productManager.changePrice(...);
    • products = productManager.add(...);
    • products = productManager.delete(...); のように、「新しい配列」をproductsに代入し直しています。
  3. productManager.list(products);で、その時点の一覧を表示しています。

重要ポイント:

  • すべてのメソッドが「元の配列を直接書き換えず、新しい配列を返す」スタイルになっています。
  • 呼び出し側では、「新しい配列をproductsに代入し直す」ことで、状態の変化を表現しています。
  • このスタイルは、ReactのState更新(setState)と非常に相性が良いです。

Reactで使うイメージと安全性の視点を重ねる

Reactコンポーネントから呼び出すイメージ

このproductManagerを、Reactコンポーネントの中で使うイメージを見てみます。

import { useState } from 'react';

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

const productManager = {
  list(products) {
    return products;
  },
  search(products, keyword) {
    return products.filter((product) =>
      product.name.includes(keyword)
    );
  },
  changePrice(products, id, newPrice) {
    return products.map((product) =>
      product.id === id
        ? { ...product, price: newPrice }
        : product
    );
  },
  add(products, newProduct) {
    return [...products, newProduct];
  },
  delete(products, id) {
    return products.filter((product) => product.id !== id);
  },
};

function ProductApp() {
  const [products, setProducts] = useState(initialProducts);
  const [keyword, setKeyword] = useState('');

  const handleSearch = () => {
    const result = productManager.search(products, keyword);
    setProducts(result);
  };

  const handleChangePrice = (id, newPrice) => {
    const updated = productManager.changePrice(products, id, newPrice);
    setProducts(updated);
  };

  const handleAdd = (newProduct) => {
    const updated = productManager.add(products, newProduct);
    setProducts(updated);
  };

  const handleDelete = (id) => {
    const updated = productManager.delete(products, id);
    setProducts(updated);
  };

  return (
    <div>
      <h2>商品データ管理</h2>

      <input
        value={keyword}
        onChange={(e) => setKeyword(e.target.value)}
        placeholder="商品名で検索"
      />
      <button onClick={handleSearch}>検索</button>

      <ul>
        {products.map((product) => (
          <li key={product.id}>
            {product.name}{product.price}円 / 在庫: {product.stock}
            <button
              onClick={() =>
                handleChangePrice(product.id, product.price + 500)
              }
            >
              500円値上げ
            </button>
            <button onClick={() => handleDelete(product.id)}>
              削除
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}
JSX

ここでのポイントは、

  • productManagerは「ロジックをまとめたオブジェクト」として外側に定義されています。
  • コンポーネント内では、
    • productManager.search
    • productManager.changePrice
    • productManager.add
    • productManager.delete を呼び出し、その結果をsetProductsでStateに反映しています。
  • すべてのメソッドが「新しい配列」を返すので、ReactのState更新と自然につながります。

セキュリティ・安全性の視点から見た「商品管理」

商品データ管理のようなプログラムでは、 セキュリティ・安全性の観点から次のような点が重要になります。

  • 外部入力(ユーザーの操作)に応じて状態を更新するときは、値の妥当性を意識すること
    • 価格がマイナスにならないか
    • 在庫数が不自然な値にならないか といったチェックが必要になる場面があります。
  • 元の配列・オブジェクトを直接書き換えないことで、予期しない副作用を防ぎやすくなること
    • 他の処理が同じ配列やオブジェクトを参照している場合でも、「新しい状態」を渡すスタイルなら影響範囲を限定しやすいです。
  • 機能をオブジェクトにまとめることで、「どこで何が起きているか」を追いやすくなること
    • productManagerの中にロジックが集約されているので、変更や拡張のときに見通しが良くなります。

DAY 10:JavaScript総合演習 中盤のまとめ

DAY 10の中盤では、

  • 前半で作った「商品一覧・検索・価格変更・追加・削除」の関数を、productManagerというオブジェクトにまとめたこと
  • 機能ごとにメソッドを分けることで、呼び出し側のコードが「何をしているか」分かりやすくなったこと
  • 一連の操作(一覧→検索→価格変更→追加→削除)を、シナリオとしてコードで書いてみたこと
  • ReactコンポーネントからproductManagerを呼び出すイメージを通して、
    • 関数
    • 配列
    • map
    • filter
    • オブジェクト
    • Spread構文 が1つの「商品データ管理プログラム」としてつながる様子を確認したこと
  • 「元の値を直接書き換えず、新しい値を返す」スタイルが、
    • 安全で予測可能な状態管理
    • セキュリティ・ユーザー体験の観点 の両方で重要であること

を整理しました。

後半では、 この商品管理プログラムをさらに「拡張しやすい形」に意識を向けながら、 今までのJavaScript基礎が「Reactで挫折しないための土台」として、 どこまで通用するかをもう一段深く体感していく流れになります。


DAY 10:JavaScript総合演習 後半 ― 「商品データ管理」を通して基礎を“実務レベル”に近づける

DAY 10の後半では、これまでに作ってきた

  • 関数
  • 配列
  • map
  • filter
  • オブジェクト
  • Spread構文

をすべて組み合わせて、商品データ管理プログラムを完成形に近づけることを目標にします。 機能は次の5つです。

  • 商品一覧
  • 商品検索
  • 価格変更
  • 商品追加
  • 商品削除

ここでは「前半・中盤・後半」に分けて、 ステップバイステップで思考しながら、初心者向けにかみ砕いて解説していきます。

完成形を意識した「設計」と「役割分担」を整理する

商品データの基本構造をもう一度確認する

まずは、扱う商品データの形を改めて確認します。 ここまでの学習を活かすなら、オブジェクト配列が最適です。

let products = [
  { id: 1, name: 'Tシャツ', price: 1200, stock: 10 },
  { id: 2, name: 'ジーンズ', price: 4800, stock: 5 },
  { id: 3, name: 'スニーカー', price: 6800, stock: 3 },
];
JavaScript
  • 1つの商品 → オブジェクト
  • 複数の商品 → オブジェクト配列

Reactでも、この構造がそのまま「状態」として使われます。

機能を「関数」として分ける理由

次に、機能ごとに関数を分けて考えます。

  • 商品一覧 → listProducts
  • 商品検索 → searchProducts
  • 価格変更 → changePrice
  • 商品追加 → addProduct
  • 商品削除 → deleteProduct

この「役割ごとに関数を分ける」考え方は、 Reactコンポーネントの分割にも直結する重要な発想です。

各機能を“安全な状態更新”として組み立てる

商品一覧 ― 配列をそのまま表示する関数

function listProducts(products) {
  products.forEach((product) => {
    console.log(
      `ID:${product.id} / 商品名:${product.name} / 価格:${product.price}円 / 在庫:${product.stock}`
    );
  });
}
JavaScript
  • forEachで1件ずつ取り出して表示します。
  • データは読み取りのみで、変更はしません。

商品検索 ― filter()で絞り込み

function searchProducts(products, keyword) {
  const result = products.filter((product) => {
    return product.name.includes(keyword);
  });

  return result;
}
JavaScript
  • filter()は「条件に合うものだけ残す」ための関数です。
  • 元のproductsは変更されず、新しい配列resultが返されます。
  • Reactの検索機能でも、このパターンがそのまま使われます。

価格変更 ― map()+Spread構文で「一部だけ更新」

function changePrice(products, id, newPrice) {
  const updatedProducts = products.map((product) => {
    if (product.id === id) {
      return {
        ...product,
        price: newPrice,
      };
    } else {
      return product;
    }
  });

  return updatedProducts;
}
JavaScript

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

  1. map()で全商品を1件ずつ処理します。
  2. product.id === id の商品だけを更新対象にします。
  3. Spread構文{ ...product, price: newPrice }
    • 元のオブジェクトをコピーし
    • priceだけを上書きした新しいオブジェクトを作ります。
  4. それ以外の商品はそのまま返します。
  5. 結果として、「1件だけ価格が変わった新しい配列」が返されます。

重要ポイント:

  • 「オブジェクト配列の一部だけを更新する」定番パターンは map+条件分岐+Spread構文です。
  • 元の配列を直接書き換えないことで、安全で予測可能な状態管理になります。

商品追加 ― Spread構文で「配列コピー+末尾追加」

function addProduct(products, newProduct) {
  const updatedProducts = [...products, newProduct];
  return updatedProducts;
}
JavaScript
  • ...productsで元の配列をコピーし、
  • newProductを末尾に追加した新しい配列を作ります。
  • 元のproductsはそのまま残ります。

ReactのState更新では、次のような形で頻出します。

setProducts([...products, newProduct]);
JavaScript

商品削除 ― filter()で「残したいものだけ残す」

function deleteProduct(products, id) {
  const updatedProducts = products.filter((product) => {
    return product.id !== id;
  });

  return updatedProducts;
}
JavaScript
  • product.id !== id の商品だけを残します。
  • 削除したい商品は「条件に合わないもの」として除外されます。
  • 元のproductsは変更されず、「削除後の一覧」が新しい配列として返されます。

機能を「連続したシナリオ」として実行し、Reactとのつながりを意識する

一連の流れをコードで実行する

ここまでの関数を使って、 商品一覧 → 検索 → 価格変更 → 追加 → 削除 という流れを1つのプログラムとして書いてみます。

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

console.log('--- 商品一覧 ---');
listProducts(products);

console.log('--- 商品検索(ジーンズ) ---');
const found = searchProducts(products, 'ジーンズ');
listProducts(found);

console.log('--- 価格変更(ID:2 → 5000円) ---');
products = changePrice(products, 2, 5000);
listProducts(products);

console.log('--- 商品追加(キャップ) ---');
const newProduct = {
  id: 4,
  name: 'キャップ',
  price: 3200,
  stock: 7,
};
products = addProduct(products, newProduct);
listProducts(products);

console.log('--- 商品削除(ID:1) ---');
products = deleteProduct(products, 1);
listProducts(products);
JavaScript

ここでのポイントは、

  • 各関数は 「新しい配列」を返す こと
  • 呼び出し側では products = ... として「状態を更新」していること
  • 元の配列を直接書き換えず、常に新しい配列を扱うスタイルになっていること

このスタイルは、Reactの

setProducts(newProducts);
JSX

というState更新と完全に同じ考え方です。

Reactで使うとどうなるか?という視点

Reactコンポーネント内では、次のような形になります。

const [products, setProducts] = useState(initialProducts);

const handleChangePrice = (id, newPrice) => {
  const updated = changePrice(products, id, newPrice);
  setProducts(updated);
};

const handleAddProduct = (newProduct) => {
  const updated = addProduct(products, newProduct);
  setProducts(updated);
};

const handleDeleteProduct = (id) => {
  const updated = deleteProduct(products, id);
  setProducts(updated);
};
JSX
  • JavaScript側で作った関数を、そのままReactの中で使えます。
  • 「配列を受け取って、新しい配列を返す」 という形が、ReactのState更新と非常に相性が良いです。

セキュリティ・安全性の観点から見たこの設計

商品データ管理のようなプログラムでは、 セキュリティ・安全性の観点から次の点が重要になります。

  • 元の配列・オブジェクトを直接書き換えないこと → 他の処理が同じ参照を持っている場合でも、予期しない副作用を防ぎやすくなります。
  • 外部入力(ユーザーの操作)に応じた更新では、値の妥当性を意識すること → 価格がマイナスにならないか、在庫数が不自然な値にならないかなどのチェックが必要になる場面があります。
  • 状態の変化が明確であること → Spread構文+mapfilterの組み合わせは、「どこがどう変わったか」を追いやすく、バグや不正な挙動を減らしやすいです。

DAY 10:JavaScript総合演習 後半のまとめ

DAY 10の後半では、

  • 関数・配列・mapfilter・オブジェクト・Spread構文を 1つの「商品データ管理プログラム」として統合したこと
  • 商品一覧・検索・価格変更・追加・削除を、 すべて「新しい配列・オブジェクトを返す」スタイルで実装したこと
  • このスタイルが、ReactのState更新(setState)と完全に同じ考え方であること
  • 安全性・拡張性・セキュリティの観点からも、 「コピーしてから一部を更新する」設計が非常に重要であること

を確認しました。

ここまでのJavaScript基礎は、 そのまま Reactで挫折しないための“土台” になっています。 この先は、コンポーネント・イベント・State管理へと進みながら、 今日作ったようなロジックを、実際の画面と結びつけていく流れになります。

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