0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React特訓03: ドロップダウンメニューでカテゴリーを選択→それに合わせたリストを表示させる

Posted at

はじめに

私がReactを学習するにあたって、AIに頼らずコードを描けるようになるために解いた問題を、アウトプットとして残していきます。

この問題はAIを使用して作成したもので、以下の流れで学習を進めたものになります。

1. AIに問題を作らせる
2. 調べながらやってみる
3. 困ったらAIに質問する
4. AIにレビューしてもらう

問題

ユーザーがドロップダウンメニューからカテゴリーを選択すると、それに合わせて関連する項目リストが表示されるコンポーネントを作ろう

要件

  • ドロップダウンメニューでカテゴリー(例:食べ物、飲み物、デザート)を選べるようにする
  • カテゴリを選択すると、そのカテゴリに関連づけられた項目(例:食べ物→「ポテチ,ポッキー,うまい棒」)がリストで表示される
  • 初期値はリストは表示されていない

ポイント

  • useStateを使った選択項目の状態管理
  • 配列やオブジェクトのデータを条件付きで画面に表示する
  • Reactのselect要素を使ったカテゴリ分けと動的な表示制御

完成系

  • 初期状態
    スクリーンショット 2025-05-05 9.15.45.png
  • ドロップダウン展開
    スクリーンショット 2025-05-05 9.16.11.png
  • それぞれをクリック
    スクリーンショット 2025-05-05 9.16.35.png
    スクリーンショット 2025-05-05 9.16.55.png
    スクリーンショット 2025-05-05 9.17.52.png

解答

import React, { useState } from 'react';

function DynamicList() {

  const [selectedCategory, setSelectedCategory] = useState(``);
  const categoryItems = {
    food: ['ポテチ', 'ポッキー', 'うまい棒'],
    drink: ['コーラ', 'ファンタ', 'スプライト'],
    desert: ['ゼリー', 'プリン', 'アイス'],
  }
  
  const handleCategoryChange = (e) => {
    setSelectedCategory(e.target.value)
  }

  return (
    <div className="p-8">
      <select className="h-14 w-[300px] bg-white appearance-none border border-blue-500 rounded-lg p-3" onChange={handleCategoryChange} value={selectedCategory}>
        <option value="">カテゴリーを選択してください</option>
        <option value="food">食べ物</option>
        <option value="drink">飲み物</option>
        <option value="desert">デザート</option>
      </select>
      <div className="mt-4">
        <ul>
          {selectedCategory &&
            categoryItems[selectedCategory].map((item, index) => <li key={index} className="w-[300px] border border-blue-200 rounded-md px-4 py-2 mb-2">{item}</li>)}
        </ul>
      </div>
    </div>
  )
}

export default DynamicList;

解説

記述の手順
1. 関数コンポーネントを作成
2. 選択されたカテゴリを管理するstateを作成
3. カテゴリごとの項目を作成
4. UIを作成
5. カテゴリを選択したときに、選択したカテゴリ名が表示されるようにする
6. イベントを作成し更新関数に値を渡す
7. mapメソッドでリストを表示

以下から順に進めます。


1. 関数コンポーネントを作成

function DynamicList() {

2. 選択されたカテゴリを管理するstateを作成

const [selectedCategory, setSelectedCategory] = useState(``);

3. カテゴリごとの項目を作成

  const categoryItems = {
    food: ['ポテチ', 'ポッキー', 'うまい棒'],
    drink: ['コーラ', 'ファンタ', 'スプライト'],
    desert: ['ゼリー', 'プリン', 'アイス'],
  }

4. UIを作成

TailWindを使用してお好みのスタイルに調整

<div className="p-8">
      <select className="h-14 w-[300px] bg-white appearance-none border border-blue-500 rounded-lg p-3">
        <option value="">カテゴリーを選択してください</option>
        <option value="food">食べ物</option>
        <option value="drink">飲み物</option>
        <option value="desert">デザート</option>
      </select>
      <div className="mt-4">
        <ul>
            <li className="w-[300px] border border-blue-200 rounded-md px-4 py-2 mb-2">
                {項目を表示}
            </li>
        </ul>
      </div>
</div>

5. カテゴリを選択したときに、選択したカテゴリ名が表示されるようにする

value属性を使用してstateと同期させる。
まだイベントは作成していないので、またクリックしても反映されない。

<select className="h-14 w-[300px] bg-white appearance-none border border-blue-500 rounded-lg p-3" value={selectedCategory}>

6. イベントを作成し更新関数に値を渡す

今回はユーザーが変更を加えたときにイベントが発火して欲しいので、onClickではなくonChangeを使用する。
ユーザーがカテゴリを変更するとhandleCategoryChange関数が発火し、更新関数にイベントによって選ばれた値を取得し、stateに保存する。

const handleCategoryChange = (e) => {
    setSelectedCategory(e.target.value)
  }

return (
    <div className="p-8">
      <select className="h-14 w-[300px] bg-white appearance-none border border-blue-500 rounded-lg p-3" onChange={handleCategoryChange} value={selectedCategory}>

7. mapメソッドでリストを表示

categoryItemsの選択されているカテゴリ(現在のstate)の配列を展開。
itemindexというキーを持たせReactが識別できるようにする。
実務においては、キーにindexを使用するのはアンチパターンなので注意。

<ul>
    {selectedCategory &&
        categoryItems[selectedCategory].map((item, index) => <li key={index} className="省略">{item}</li>)}
 </ul>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?