はじめに
私がReactを学習するにあたって、AIに頼らずコードを描けるようになるために解いた問題を、アウトプットとして残していきます。
この問題はAIを使用して作成したもので、以下の流れで学習を進めたものになります。
1. AIに問題を作らせる
2. 調べながらやってみる
3. 困ったらAIに質問する
4. AIにレビューしてもらう
問題
ユーザーがドロップダウンメニューからカテゴリーを選択すると、それに合わせて関連する項目リストが表示されるコンポーネントを作ろう
要件
- ドロップダウンメニューでカテゴリー(例:食べ物、飲み物、デザート)を選べるようにする
- カテゴリを選択すると、そのカテゴリに関連づけられた項目(例:食べ物→「ポテチ,ポッキー,うまい棒」)がリストで表示される
- 初期値はリストは表示されていない
ポイント
- useStateを使った選択項目の状態管理
- 配列やオブジェクトのデータを条件付きで画面に表示する
- Reactのselect要素を使ったカテゴリ分けと動的な表示制御
完成系
解答
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
)の配列を展開。
各item
にindex
というキーを持たせReactが識別できるようにする。
実務においては、キーにindex
を使用するのはアンチパターンなので注意。
<ul>
{selectedCategory &&
categoryItems[selectedCategory].map((item, index) => <li key={index} className="省略">{item}</li>)}
</ul>