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

React 60日で身につけるReact
スポンサーリンク
スポンサーリンク

Day 10:JavaScript総合演習で「商品データ管理プログラム」を作る

Day 10は、ここまで学んできた 関数・配列・map・filter・オブジェクト・Spread構文 を総合的に組み合わせて、 実際に使える形の 「商品データ管理プログラム」 を作っていく回です。

ここまでできれば、Reactで同じことを「画面付き」で動かす世界に進んでいけます。 少し長めですが、ひとつひとつの機能を丁寧につないでいきます。

商品データの設計:オブジェクト配列で「商品一覧」を表現する

まずは、プログラムの中心になる「商品データ」を決めます。 ここでは、次のような情報を持つ商品オブジェクトを使います。

  • id:商品を一意に識別する番号
  • name:商品名
  • price:価格
  • inStock:在庫があるかどうか(true / false)

これを配列に並べて「商品一覧」として扱います。

// --- 商品データ(オブジェクト配列) ---
// ここが「商品一覧」の元データになります
let products = [
  { id: 1, name: "Tシャツ", price: 1000, inStock: true },
  { id: 2, name: "パーカー", price: 2500, inStock: false },
  { id: 3, name: "キャップ", price: 1500, inStock: true },
];
JavaScript
  • let を使っているのは、「あとで配列を差し替える(更新する)」ためです。
  • Reactでは useState を使って同じようなことをしますが、ここでは素のJavaScriptでイメージをつかみます。

関数①:商品一覧を表示する(一覧機能)

まずは基本の「商品一覧」を表示する関数を作ります。 ここでは、map を使って「1商品 → 1行の文字列」に変換し、それをまとめて表示します。

// --- 商品一覧を表示する関数 ---
const showProducts = () => {
  console.log("=== 商品一覧 ===");

  // products配列をmapで「表示用の文字列」に変換します
  const lines = products.map((product) => {
    // 1つの商品オブジェクトから、表示用のテキストを作ります
    const stockLabel = product.inStock ? "在庫あり" : "在庫なし";

    return `ID: ${product.id} / 商品名: ${product.name} / 価格: ${product.price}円 / ${stockLabel}`;
  });

  // 1行ずつ表示します
  lines.forEach((line) => {
    console.log(line);
  });

  console.log(""); // 見やすさのために空行
};

// 実行してみます
showProducts();
JavaScript

ここで使っているポイントは:

  • 配列:products が商品一覧
  • map:各商品を「表示用の文字列」に変換
  • 関数:showProducts として処理をひとまとめにして、何度でも呼び出せるようにしている

この「一覧表示」は、Reactでは <ul> や <table> に変わっていきます。

関数②:商品検索(filterで絞り込み)

次に、「商品検索」機能を作ります。 ここでは、商品名にキーワードを含むものだけを filter で絞り込みます。

// --- 商品検索(キーワードで絞り込み) ---
const searchProductsByName = (keyword) => {
  console.log(`=== 商品検索:キーワード「${keyword}」 ===`);

  // filterで「名前にキーワードを含む商品だけ」を絞り込みます
  const matched = products.filter((product) => {
    return product.name.includes(keyword);
  });

  if (matched.length === 0) {
    console.log("該当する商品がありませんでした。");
    console.log("");
    return;
  }

  // 結果を表示します(一覧表示と同じような形)
  matched.forEach((product) => {
    const stockLabel = product.inStock ? "在庫あり" : "在庫なし";
    console.log(`ID: ${product.id} / 商品名: ${product.name} / 価格: ${product.price}円 / ${stockLabel}`);
  });

  console.log("");
};

// 実行例
searchProductsByName("Tシャツ");
searchProductsByName("パー");
JavaScript

ここで使っているポイントは:

  • filter:条件に合う商品だけを「新しい配列」として取り出す
  • 検索処理:includes で部分一致検索
  • 見つからない場合はメッセージを表示

Reactでは、この関数の中身が「入力されたキーワードに応じて表示する商品を変えるロジック」になります。

関数③:価格変更(map+Spreadで一部更新)

次は、「特定の商品だけ価格を変更する」機能です。 ここでは、map と Spread構文を組み合わせて、「一部だけ変更した新しい配列」を作ります。

// --- 価格変更(IDで指定して価格を更新) ---
const changeProductPrice = (id, newPrice) => {
  console.log(`=== 価格変更:ID=${id} を ${newPrice}円に変更 ===`);

  // productsをmapして、「対象IDだけ価格を変更した新しい配列」を作ります
  const updated = products.map((product) => {
    if (product.id === id) {
      // 対象の商品だけ、Spread構文でコピー+priceを上書きします
      return {
        ...product,      // もとのプロパティをコピー
        price: newPrice, // priceだけ新しい値にする
      };
    }

    // それ以外の商品はそのまま返します
    return product;
  });

  // 新しい配列でproductsを置き換えます
  products = updated;

  // 結果を表示します
  showProducts();
};

// 実行例
changeProductPrice(2, 2800);
JavaScript

ここで使っているポイントは:

  • map:配列の各要素を「変えるか・そのままか」で新しい配列にする
  • Spread構文:{ ...product, price: newPrice } で「コピー+一部上書き」
  • State更新のイメージ:products = updated; が、Reactの setProducts(updated) に対応する感覚

この「コピーして一部だけ変える」パターンは、ReactのState更新で非常に重要です。

関数④:商品追加(Spreadで配列に新しい要素を足す)

次は、「商品追加」機能です。 新しい商品オブジェクトを作り、Spread構文で配列に追加します。

// --- 商品追加 ---
const addProduct = (name, price, inStock) => {
  console.log(`=== 商品追加:${name} (${price}円) ===`);

  // 新しいIDを決めます(ここでは単純に最大ID+1とします)
  const maxId = products.length > 0 ? Math.max(...products.map((p) => p.id)) : 0;
  const newId = maxId + 1;

  // 新しい商品オブジェクトを作ります
  const newProduct = {
    id: newId,
    name,
    price,
    inStock,
  };

  // Spread構文で「元の配列+新しい商品」の新しい配列を作ります
  products = [...products, newProduct];

  // 結果を表示します
  showProducts();
};

// 実行例
addProduct("スニーカー", 5000, true);
JavaScript

ここで使っているポイントは:

  • オブジェクト:新しい商品データを1つのオブジェクトとして作る
  • Spread構文(配列):[...products, newProduct] で「末尾に追加」
  • IDの決め方はシンプルですが、「一意なIDを振る」という発想が大事です

Reactでは、フォームから入力された値を使って同じような処理を行います。

関数⑤:商品削除(filterで「残したいものだけ」を残す)

最後に、「商品削除」機能です。 ここでは、filter を使って「削除したいID以外の商品だけ」を残します。

// --- 商品削除 ---
const deleteProduct = (id) => {
  console.log(`=== 商品削除:ID=${id} を削除 ===`);

  // filterで「idが一致しないものだけ」を残します
  const updated = products.filter((product) => {
    return product.id !== id;
  });

  products = updated;

  // 結果を表示します
  showProducts();
};

// 実行例
deleteProduct(1);
JavaScript

ここで使っているポイントは:

  • filter:条件に合うものだけを残す(ここでは「削除したいID以外」)
  • 「削除したいものを指定する」のではなく、「残したいものの条件を書く」という発想

ReactのState更新でも、削除処理はほぼこの形になります。

総合テンプレート:商品データ管理プログラム全体

ここまでのコードをひとつにまとめた「総合テンプレート」を載せます。 このままコピペして、ブラウザのコンソールやNode.jsで動かして試せる形になっています。

// --- Day 10 商品データ管理プログラム 総合テンプレート ---

// 商品一覧(オブジェクト配列)
let products = [
  { id: 1, name: "Tシャツ", price: 1000, inStock: true },
  { id: 2, name: "パーカー", price: 2500, inStock: false },
  { id: 3, name: "キャップ", price: 1500, inStock: true },
];

// 商品一覧表示
const showProducts = () => {
  console.log("=== 商品一覧 ===");

  const lines = products.map((product) => {
    const stockLabel = product.inStock ? "在庫あり" : "在庫なし";
    return `ID: ${product.id} / 商品名: ${product.name} / 価格: ${product.price}円 / ${stockLabel}`;
  });

  lines.forEach((line) => {
    console.log(line);
  });

  console.log("");
};

// 商品検索(名前で検索)
const searchProductsByName = (keyword) => {
  console.log(`=== 商品検索:キーワード「${keyword}」 ===`);

  const matched = products.filter((product) => product.name.includes(keyword));

  if (matched.length === 0) {
    console.log("該当する商品がありませんでした。");
    console.log("");
    return;
  }

  matched.forEach((product) => {
    const stockLabel = product.inStock ? "在庫あり" : "在庫なし";
    console.log(`ID: ${product.id} / 商品名: ${product.name} / 価格: ${product.price}円 / ${stockLabel}`);
  });

  console.log("");
};

// 価格変更(ID指定)
const changeProductPrice = (id, newPrice) => {
  console.log(`=== 価格変更:ID=${id} を ${newPrice}円に変更 ===`);

  const updated = products.map((product) => {
    if (product.id === id) {
      return {
        ...product,
        price: newPrice,
      };
    }
    return product;
  });

  products = updated;
  showProducts();
};

// 商品追加
const addProduct = (name, price, inStock) => {
  console.log(`=== 商品追加:${name} (${price}円) ===`);

  const maxId = products.length > 0 ? Math.max(...products.map((p) => p.id)) : 0;
  const newId = maxId + 1;

  const newProduct = {
    id: newId,
    name,
    price,
    inStock,
  };

  products = [...products, newProduct];
  showProducts();
};

// 商品削除
const deleteProduct = (id) => {
  console.log(`=== 商品削除:ID=${id} を削除 ===`);

  const updated = products.filter((product) => product.id !== id);

  products = updated;
  showProducts();
};

// --- 実行例 ---
// 初期一覧
showProducts();

// 検索
searchProductsByName("Tシャツ");
searchProductsByName("パー");

// 価格変更
changeProductPrice(2, 2800);

// 商品追加
addProduct("スニーカー", 5000, true);

// 商品削除
deleteProduct(1);
JavaScript

このテンプレートをベースにして、

  • 商品データを自分の好きなジャンル(本、ゲーム、映画など)に変えてみる
  • 検索条件を増やしてみる(価格帯、在庫ありのみなど)
  • 価格変更を「割引率」で計算するようにしてみる

といったアレンジを加えていくと、「自分の手で作ったプログラム」という感覚がぐっと強くなっていきます。

Day 10のまとめ:Reactへつながる「土台」がそろった状態

この総合演習で扱った要素は、すべてReactでそのまま使われます。

  • 関数:機能ごとに処理をまとめる
  • 配列:一覧データを管理する
  • map:一覧データを「表示用の形」に変換する
  • filter:検索・削除・絞り込みを行う
  • オブジェクト:意味のあるデータをひとまとまりで扱う
  • Spread構文:元のデータを壊さずにコピーし、一部だけ変更する

ここまでできていれば、Reactでは

  • products が「state」になり、
  • showProducts の中身が「コンポーネントのJSX」になり、
  • addProduct や deleteProduct が「ボタンのクリックイベントハンドラ」になっていく

という流れで、画面付きのアプリに進化していきます。

Day 10は、まさに「Reactへ進むための準備が整った日」です。 この商品データ管理プログラムを、自分なりに少し遊びながら触ってみてから、次のReact編に進んでいくと、理解の深さがまったく違ってくるはずです。

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