--- title: "Reactで複数選択比較機能を実装する方法|useStateとアクセシビリティ対応完全ガイド" description: "Reactで複数選択比較機能を実装する方法を徹底解説。useStateを使った選択状態管理、Setと配列の組み合わせパターン、モーダルのアクセシビリティ(フォーカストラップ)対応まで、実践的なコード例と共に紹介します。" created: "2026-01-01" status: "draft" platforms: wordpress: published: false url: "" published_date: "" category: "react-nextjs/ui" tags: - "React Hooks" - "useState" - "複数選択" - "モーダル" - "状態管理" - "アクセシビリティ" - "フォーカストラップ" --- ![Reactによる複数選択比較機能のUI実装図。useState、useEffect、配列ロジック、フォーカストラップなど、技術的要素を解説。](https://wakatchi.dev/wp-content/uploads/2026/02/implementing-comparison-feature-in-react-eyecatch.webp) ## はじめに:Reactで複数選択比較機能を実装する方法 お気に入り一覧ページに「複数のアイテムを横並びで比較する機能」が必要になりました。 ユーザーが2〜4個のアイテムを選択し、価格・サービス・営業時間などの情報を一覧で比較できるモーダル形式のUIを実装しました。 本記事では、**Reactで複数選択機能を実装する方法**について、実際のコード例を交えながら詳しく解説します。 具体的には以下のトピックをカバーします。 - useStateを使った選択状態管理のベストプラクティス - Setと配列を組み合わせた高速な選択パターン - Prune Logicによる外部状態との同期方法 - モーダルのアクセシビリティ対応(フォーカストラップ、スクロールロック) - 実践的なテスト戦略 ## こんな人におすすめ - **Reactで複数選択機能**を実装したい方 - useStateを使った**選択状態管理**のベストプラクティスを知りたい方 - **Reactモーダル**のアクセシビリティ対応(フォーカストラップ)に関心がある方 - **Prune Logic**(外部状態との同期)を実装したい方 - 比較機能やテーブル表示を実装する際の設計パターンを学びたい方 ## 目次 - [はじめに:Reactで複数選択比較機能を実装する方法](#はじめにreactで複数選択比較機能を実装する方法) - [こんな人におすすめ](#こんな人におすすめ) - [React比較機能の要件定義](#react比較機能の要件定義) - [Reactでの実装方針:useStateと型定義](#reactでの実装方針usestateと型定義) - [1. 型定義と定数](#1-型定義と定数srctypescomparets) - [2. useStateで複数選択状態を管理する方法](#2-usestateで複数選択状態を管理する方法) - [3. Prune Logic:外部状態と選択状態の同期方法](#3-prune-logic外部状態と選択状態の同期方法) - [4. Reactモーダルのアクセシビリティ対応](#4-reactモーダルのアクセシビリティ対応) - [5. 比較データの差異ハイライト実装](#5-比較データの差異ハイライト実装) - [ポイント](#ポイント) - [選択順の保持](#選択順の保持) - [イベント伝播の制御](#イベント伝播の制御アイテムカード) - [データフォールバック](#データフォールバック) - [学び](#学び) - [1. 選択状態の管理パターン](#1-選択状態の管理パターン) - [2. Prune Logicの重要性](#2-prune-logicの重要性) - [3. メタデータ駆動設計](#3-メタデータ駆動設計) - [4. モーダルのアクセシビリティ](#4-モーダルのアクセシビリティ) - [テスト戦略](#テスト戦略) - [よくある質問:React複数選択機能の実装について](#よくある質問react複数選択機能の実装について) - [Q1: Reactで複数選択機能を実装する最も簡単な方法は?](#q1-reactで複数選択機能を実装する最も簡単な方法は) - [Q2: useStateで選択状態を管理する際のパフォーマンスは?](#q2-usestateで選択状態を管理する際のパフォーマンスは) - [Q3: モーダルのフォーカストラップとは何ですか?](#q3-モーダルのフォーカストラップとは何ですか) - [Q4: Prune Logicとはどういう意味ですか?](#q4-prune-logicとはどういう意味ですか) - [Q5: Reactモーダル実装でよくあるバグは?](#q5-reactモーダル実装でよくあるバグは) - [まとめ:React複数選択比較機能の実装ガイド](#まとめreact複数選択比較機能の実装ガイド) ## React比較機能の要件定義 実装する比較機能の要件を整理します。 - 比較モードのON/OFF切り替えができること - 2〜4個のアイテムを選択可能(選択順で表示) - モーダル形式で横並び比較テーブルを表示 - アイテム間で値が異なる行を黄色背景でハイライト - お気に入り解除時に選択状態を自動同期(prune logic) - フォーカストラップ+スクロールロック対応 - ESCキー、オーバーレイクリック、閉じるボタンで閉じます ```mermaid stateDiagram-v2 [*] --> 通常モード 通常モード --> 比較モード: トグルON 比較モード --> 通常モード: トグルOFF 比較モード --> 比較テーブル表示: 2社以上選択 比較テーブル表示 --> 比較モード: 選択数が2社未満 比較テーブル表示 --> 通常モード: 閉じる操作 note right of 比較モード 最大4社まで選択可能 選択順を保持 end note ``` ## Reactでの実装方針:useStateと型定義 ### 1. 型定義と定数(`src/types/compare.ts`) ```typescript export const MAX_COMPARE_SELECTION = 4; export const MIN_COMPARE_SELECTION = 2; export interface CompareField { key: string; label: string; icon?: string; getValue: (company: Company) => string | string[]; getNormalizedValue: (company: Company) => string; } export const COMPARE_FIELDS: CompareField[] = [ { key: 'unitPrice', label: '単価', /* ... */ }, { key: 'wasteTypes', label: '対応廃棄物', /* ... */ }, // ... ]; ``` 比較項目をメタデータ駆動で定義。拡張性を確保。 ### 2. useStateで複数選択状態を管理する方法 ```typescript const [isCompareMode, setIsCompareMode] = React.useState(false); const [selectedForCompare, setSelectedForCompare] = React.useState<Set<string>>(new Set()); const [selectedOrder, setSelectedOrder] = React.useState<string[]>([]); const [showCompareTable, setShowCompareTable] = React.useState(false); ``` - `Set` で選択状態を管理します(O(1)の存在チェック) - 配列で選択順を保持します(表示順を制御) ```mermaid graph LR A[Set<string>] -->|高速検索 O1| B[選択状態管理] C[string配列] -->|順序保持| D[表示順制御] B --> E[選択操作] D --> E style A fill:#e1f5fe style C fill:#fff3e0 style E fill:#c8e6c9 ``` ### 3. Prune Logic:外部状態と選択状態の同期方法 ```typescript React.useEffect(() => { setSelectedForCompare(prev => { const pruned = new Set([...prev].filter(id => bookmarkedIds.has(id))); if (pruned.size < MIN_COMPARE_SELECTION && showCompareTable) { setShowCompareTable(false); } return pruned; }); setSelectedOrder(prev => prev.filter(id => bookmarkedIds.has(id))); }, [bookmarkedIds, showCompareTable]); ``` お気に入りアイテムが削除されたら、選択状態から自動的に除外します。最小選択数を下回ったら比較テーブルを閉じます。 **Prune Logic**とは、外部状態(お気に入り)が変化した際に、依存する状態(選択)を自動的に同期するパターンです。 ```mermaid flowchart TD A[お気に入り削除] --> B{選択状態に含まれる?} B -->|はい| C[選択状態から除外] B -->|いいえ| D[何もしない] C --> E{選択数 < 2?} E -->|はい| F[比較テーブルを閉じる] E -->|いいえ| G[表示を維持] style A fill:#ffcdd2 style F fill:#fff9c4 style G fill:#c8e6c9 ``` ### 4. Reactモーダルのアクセシビリティ対応 **アクセシビリティ対応**はモーダル実装で最も重要な要素です。 - **フォーカストラップ**: キーボードユーザーがTabキーで操作する際、フォーカスがモーダル外に逃げないようにする機能 - **スクロールロック**: `body` に `overflow: hidden` を適用 - **ESCキー対応**: `keydown` イベントで閉じる処理 ※ フォーカストラップの詳細な実装方法は、後述の「Q3: モーダルのフォーカストラップとは何ですか?」で解説しています。 ### 5. 比較データの差異ハイライト実装 ```typescript export function hasValueDifference( companies: Company[], field: CompareField ): boolean { const normalizedValues = companies.map(field.getNormalizedValue); const uniqueValues = new Set(normalizedValues); return uniqueValues.size > 1; } ``` 正規化した値で比較します。1つでも異なる値があれば `true` です。 ## ポイント ### 選択順の保持 ```typescript const handleToggleCompareSelection = (companyId: string) => { setSelectedForCompare(prev => { const newSet = new Set(prev); if (newSet.has(companyId)) { newSet.delete(companyId); setSelectedOrder(order => order.filter(id => id !== companyId)); } else if (newSet.size < MAX_COMPARE_SELECTION) { newSet.add(companyId); setSelectedOrder(order => [...order, companyId]); } return newSet; }); }; ``` `Set` と配列を同時に更新します。Setで高速検索、配列で順序を保証します。 ### イベント伝播の制御(アイテムカード) 比較モード時はカードクリックで選択切替、通常モードは詳細モーダル表示します。 ```typescript const handleCardClick = () => { if (isCompareMode) { if (!isSelectionDisabled || isSelectedForCompare) { onToggleCompareSelection?.(); } } else { onCardClick(); } }; ``` お気に入り解除ボタンは `stopPropagation()` でカードクリックに影響しないようにします。 ### データフォールバック ```typescript const operatingHours = company.operatingHours || (company.businessHours ? `平日: ${company.businessHours}` : '情報なし'); ``` `operatingHours` が空なら `businessHours` から生成します。どちらもなければ「情報なし」と表示します。 ## 学び ### 1. 選択状態の管理パターン `Set<string>` + `string[]` の組み合わせは、高速検索と順序保持を両立する良いパターンです。 正直なところ、実装当初は配列だけで管理しようとしていましたが、検索性能の問題に気づきました。個人的には、この組み合わせパターンを知っておけば、他の選択機能でも応用できると感じています。 ### 2. Prune Logicの重要性 外部状態(お気に入りアイテム)が変化したら、依存する状態(選択)を自動同期します。`useEffect` で監視することで整合性を保証します。 実際に、この同期処理を忘れていて「お気に入りアイテムを削除しても比較テーブルに残り続ける」というバグに遭遇しました。`useEffect` の依存配列を意識することの重要性を痛感しました。 ### 3. メタデータ駆動設計 比較項目を `COMPARE_FIELDS` 配列で定義することで、項目の追加・削除が容易です。各フィールドに `getValue` と `getNormalizedValue` を持たせることで、表示と比較のロジックを分離しています。 ### 4. モーダルのアクセシビリティ フォーカストラップとスクロールロックは別々の責務です。カスタムフック化することで再利用性が向上します(後のリファクタリングで `useFocusTrap`、`useScrollLock` に分離)。 ## テスト戦略 - **比較モードの切り替え**: トグルON/OFFで選択状態がクリアされるか - **選択操作**: 2〜4個のアイテム選択、最大数到達時の無効化 - **比較テーブル表示**: 2個以上選択時にボタンが有効化 - **Prune Logic**: お気に入り削除時に選択から自動除外 - **差異ハイライト**: 値が異なる行が黄色背景になるか 全54テスト実装、すべて通過しました。 ## よくある質問:React複数選択機能の実装について ### Q1: Reactで複数選択機能を実装する最も簡単な方法は? **A**: useStateと配列を使うのが最も簡単です。以下のコードで基本的な複数選択が実装できます。 ```typescript const [selectedIds, setSelectedIds] = useState<string[]>([]); const toggleSelection = (id: string) => { setSelectedIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id] ); }; ``` ただし、選択数が多くなる場合は、本記事で紹介しているSetと配列の組み合わせパターンが推奨されます。 ### Q2: useStateで選択状態を管理する際のパフォーマンスは? **A**: 小規模(100件以下)であれば配列のみで問題ありません。中規模以上ではSetとの併用で検索パフォーマンスが向上します。 - 配列のみ: O(n)の検索コスト - Setのみ: O(1)の検索コスト(順序保持なし) - Set + 配列: O(1)の検索 + 順序保持 ### Q3: モーダルのフォーカストラップとは何ですか? **A**: フォーカストラップとは、キーボードユーザーがTabキーで操作する際、フォーカスがモーダル外に逃げないようにするアクセシビリティ機能です。 具体的には以下を実装します。 - 最初の要素でShift+Tab時に最後の要素にフォーカス - 最後の要素でTab時に最初の要素にフォーカス - モーダルが開いた時に最初のフォーカス可能要素にフォーカス - モーダルが閉じた時に元の要素にフォーカスを戻す ### Q4: Prune Logicとはどういう意味ですか? **A**: Prune(剪定)Logicとは、外部状態が変化した際に、依存する状態から不要な要素を自動的に削除するパターンです。 本記事の例では、お気に入りアイテムが削除されたら、選択状態から自動的に除外する処理を指します。 ### Q5: Reactモーダル実装でよくあるバグは? **A**: よくあるバグと対策は以下の通りです。 | バグ | 原因 | 対策 | |-----|------|------| | 背景スクロールが有効 | bodyのoverflow設定忘れ | `overflow: hidden`を適用 | | フォーカスが逃げる | フォーカストラップ未実装 | Tabキーでループ処理を実装 | | ESCキーで閉じない | イベントリスナー未設定 | keydownイベントを監視 | | 重複レンダリング | 不適切な依存配列 | useEffectの依存配列を最適化 | ## まとめ:React複数選択比較機能の実装ガイド 本記事では、Reactで複数選択比較機能を実装する方法について解説しました。 ### 重要なポイント 1. **選択状態管理**: useStateでSetと配列を組み合わせると、高速検索と順序保持を両立できます 2. **Prune Logic**: 外部状態が変化したら、useEffectで自動的に同期します 3. **アクセシビリティ**: フォーカストラップとスクロールロックは別々の責務として実装します 4. **メタデータ駆動**: 比較項目を配列で定義すると、拡張性が高まります ### 次のステップ この実装パターンは、比較機能以外にも以下のようなケースで応用できます。 - ショッピングサイトの商品比較 - 不動産サイトの物件比較 - サービス比較サイトの機能比較 - プラン比較・料金表の実装 記事内で紹介したコードは、すべて実際に動作する実装です。 ぜひ参考にして、自分のプロジェクトで複数選択機能を実装してみてください。

Reactによる複数選択比較機能のUI実装図。useState、useEffect、配列ロジック、フォーカストラップなど、技術的要素を解説。

はじめに:Reactで複数選択比較機能を実装する方法

お気に入り一覧ページに「複数のアイテムを横並びで比較する機能」が必要になりました。

ユーザーが2〜4個のアイテムを選択し、価格・サービス・営業時間などの情報を一覧で比較できるモーダル形式のUIを実装しました。

本記事では、Reactで複数選択機能を実装する方法について、実際のコード例を交えながら詳しく解説します。

具体的には以下のトピックをカバーします。

  • useStateを使った選択状態管理のベストプラクティス
  • Setと配列を組み合わせた高速な選択パターン
  • Prune Logicによる外部状態との同期方法
  • モーダルのアクセシビリティ対応(フォーカストラップ、スクロールロック)
  • 実践的なテスト戦略

こんな人におすすめ

  • Reactで複数選択機能を実装したい方
  • useStateを使った選択状態管理のベストプラクティスを知りたい方
  • Reactモーダルのアクセシビリティ対応(フォーカストラップ)に関心がある方
  • Prune Logic(外部状態との同期)を実装したい方
  • 比較機能やテーブル表示を実装する際の設計パターンを学びたい方

目次

React比較機能の要件定義

実装する比較機能の要件を整理します。

  • 比較モードのON/OFF切り替えができること
  • 2〜4個のアイテムを選択可能(選択順で表示)
  • モーダル形式で横並び比較テーブルを表示
  • アイテム間で値が異なる行を黄色背景でハイライト
  • お気に入り解除時に選択状態を自動同期(prune logic)
  • フォーカストラップ+スクロールロック対応
  • ESCキー、オーバーレイクリック、閉じるボタンで閉じます
stateDiagram-v2
    [*] --> 通常モード
    通常モード --> 比較モード: トグルON
    比較モード --> 通常モード: トグルOFF
    比較モード --> 比較テーブル表示: 2社以上選択
    比較テーブル表示 --> 比較モード: 選択数が2社未満
    比較テーブル表示 --> 通常モード: 閉じる操作

    note right of 比較モード
        最大4社まで選択可能
        選択順を保持
    end note

Reactでの実装方針:useStateと型定義

1. 型定義と定数(src/types/compare.ts

export const MAX_COMPARE_SELECTION = 4;
export const MIN_COMPARE_SELECTION = 2;

export interface CompareField {
  key: string;
  label: string;
  icon?: string;
  getValue: (company: Company) => string | string[];
  getNormalizedValue: (company: Company) => string;
}

export const COMPARE_FIELDS: CompareField[] = [
  { key: 'unitPrice', label: '単価', /* ... */ },
  { key: 'wasteTypes', label: '対応廃棄物', /* ... */ },
  // ...
];

比較項目をメタデータ駆動で定義。拡張性を確保。

2. useStateで複数選択状態を管理する方法

const [isCompareMode, setIsCompareMode] = React.useState(false);
const [selectedForCompare, setSelectedForCompare] = React.useState<Set<string>>(new Set());
const [selectedOrder, setSelectedOrder] = React.useState<string[]>([]);
const [showCompareTable, setShowCompareTable] = React.useState(false);
  • Set で選択状態を管理します(O(1)の存在チェック)
  • 配列で選択順を保持します(表示順を制御)
graph LR
    A[Set&lt;string&gt;] -->|高速検索 O1| B[選択状態管理]
    C[string配列] -->|順序保持| D[表示順制御]
    B --> E[選択操作]
    D --> E

    style A fill:#e1f5fe
    style C fill:#fff3e0
    style E fill:#c8e6c9

3. Prune Logic:外部状態と選択状態の同期方法

React.useEffect(() => {
  setSelectedForCompare(prev => {
    const pruned = new Set([...prev].filter(id => bookmarkedIds.has(id)));
    if (pruned.size < MIN_COMPARE_SELECTION && showCompareTable) {
      setShowCompareTable(false);
    }
    return pruned;
  });
  setSelectedOrder(prev => prev.filter(id => bookmarkedIds.has(id)));
}, [bookmarkedIds, showCompareTable]);

お気に入りアイテムが削除されたら、選択状態から自動的に除外します。最小選択数を下回ったら比較テーブルを閉じます。

Prune Logicとは、外部状態(お気に入り)が変化した際に、依存する状態(選択)を自動的に同期するパターンです。

flowchart TD
    A[お気に入り削除] --> B{選択状態に含まれる?}
    B -->|はい| C[選択状態から除外]
    B -->|いいえ| D[何もしない]
    C --> E{選択数 < 2?}
    E -->|はい| F[比較テーブルを閉じる]
    E -->|いいえ| G[表示を維持]

    style A fill:#ffcdd2
    style F fill:#fff9c4
    style G fill:#c8e6c9

4. Reactモーダルのアクセシビリティ対応

アクセシビリティ対応はモーダル実装で最も重要な要素です。

  • フォーカストラップ: キーボードユーザーがTabキーで操作する際、フォーカスがモーダル外に逃げないようにする機能
  • スクロールロック: bodyoverflow: hidden を適用
  • ESCキー対応: keydown イベントで閉じる処理

※ フォーカストラップの詳細な実装方法は、後述の「Q3: モーダルのフォーカストラップとは何ですか?」で解説しています。

5. 比較データの差異ハイライト実装

export function hasValueDifference(
  companies: Company[],
  field: CompareField
): boolean {
  const normalizedValues = companies.map(field.getNormalizedValue);
  const uniqueValues = new Set(normalizedValues);
  return uniqueValues.size > 1;
}

正規化した値で比較します。1つでも異なる値があれば true です。

ポイント

選択順の保持

const handleToggleCompareSelection = (companyId: string) => {
  setSelectedForCompare(prev => {
    const newSet = new Set(prev);
    if (newSet.has(companyId)) {
      newSet.delete(companyId);
      setSelectedOrder(order => order.filter(id => id !== companyId));
    } else if (newSet.size < MAX_COMPARE_SELECTION) {
      newSet.add(companyId);
      setSelectedOrder(order => [...order, companyId]);
    }
    return newSet;
  });
};

Set と配列を同時に更新します。Setで高速検索、配列で順序を保証します。

イベント伝播の制御(アイテムカード)

比較モード時はカードクリックで選択切替、通常モードは詳細モーダル表示します。

const handleCardClick = () => {
  if (isCompareMode) {
    if (!isSelectionDisabled || isSelectedForCompare) {
      onToggleCompareSelection?.();
    }
  } else {
    onCardClick();
  }
};

お気に入り解除ボタンは stopPropagation() でカードクリックに影響しないようにします。

データフォールバック

const operatingHours = company.operatingHours ||
  (company.businessHours ? `平日: ${company.businessHours}` : '情報なし');

operatingHours が空なら businessHours から生成します。どちらもなければ「情報なし」と表示します。

学び

1. 選択状態の管理パターン

Set<string> + string[] の組み合わせは、高速検索と順序保持を両立する良いパターンです。

正直なところ、実装当初は配列だけで管理しようとしていましたが、検索性能の問題に気づきました。個人的には、この組み合わせパターンを知っておけば、他の選択機能でも応用できると感じています。

2. Prune Logicの重要性

外部状態(お気に入りアイテム)が変化したら、依存する状態(選択)を自動同期します。useEffect で監視することで整合性を保証します。

実際に、この同期処理を忘れていて「お気に入りアイテムを削除しても比較テーブルに残り続ける」というバグに遭遇しました。useEffect の依存配列を意識することの重要性を痛感しました。

3. メタデータ駆動設計

比較項目を COMPARE_FIELDS 配列で定義することで、項目の追加・削除が容易です。各フィールドに getValuegetNormalizedValue を持たせることで、表示と比較のロジックを分離しています。

4. モーダルのアクセシビリティ

フォーカストラップとスクロールロックは別々の責務です。カスタムフック化することで再利用性が向上します(後のリファクタリングで useFocusTrapuseScrollLock に分離)。

テスト戦略

  • 比較モードの切り替え: トグルON/OFFで選択状態がクリアされるか
  • 選択操作: 2〜4個のアイテム選択、最大数到達時の無効化
  • 比較テーブル表示: 2個以上選択時にボタンが有効化
  • Prune Logic: お気に入り削除時に選択から自動除外
  • 差異ハイライト: 値が異なる行が黄色背景になるか

全54テスト実装、すべて通過しました。

よくある質問:React複数選択機能の実装について

Q1: Reactで複数選択機能を実装する最も簡単な方法は?

A: useStateと配列を使うのが最も簡単です。以下のコードで基本的な複数選択が実装できます。

const [selectedIds, setSelectedIds] = useState<string[]>([]);

const toggleSelection = (id: string) => {
  setSelectedIds(prev =>
    prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]
  );
};

ただし、選択数が多くなる場合は、本記事で紹介しているSetと配列の組み合わせパターンが推奨されます。

Q2: useStateで選択状態を管理する際のパフォーマンスは?

A: 小規模(100件以下)であれば配列のみで問題ありません。中規模以上ではSetとの併用で検索パフォーマンスが向上します。

  • 配列のみ: O(n)の検索コスト
  • Setのみ: O(1)の検索コスト(順序保持なし)
  • Set + 配列: O(1)の検索 + 順序保持

Q3: モーダルのフォーカストラップとは何ですか?

A: フォーカストラップとは、キーボードユーザーがTabキーで操作する際、フォーカスがモーダル外に逃げないようにするアクセシビリティ機能です。

具体的には以下を実装します。

  • 最初の要素でShift+Tab時に最後の要素にフォーカス
  • 最後の要素でTab時に最初の要素にフォーカス
  • モーダルが開いた時に最初のフォーカス可能要素にフォーカス
  • モーダルが閉じた時に元の要素にフォーカスを戻す

Q4: Prune Logicとはどういう意味ですか?

A: Prune(剪定)Logicとは、外部状態が変化した際に、依存する状態から不要な要素を自動的に削除するパターンです。

本記事の例では、お気に入りアイテムが削除されたら、選択状態から自動的に除外する処理を指します。

Q5: Reactモーダル実装でよくあるバグは?

A: よくあるバグと対策は以下の通りです。

バグ 原因 対策
背景スクロールが有効 bodyのoverflow設定忘れ overflow: hiddenを適用
フォーカスが逃げる フォーカストラップ未実装 Tabキーでループ処理を実装
ESCキーで閉じない イベントリスナー未設定 keydownイベントを監視
重複レンダリング 不適切な依存配列 useEffectの依存配列を最適化

まとめ:React複数選択比較機能の実装ガイド

本記事では、Reactで複数選択比較機能を実装する方法について解説しました。

重要なポイント

  1. 選択状態管理: useStateでSetと配列を組み合わせると、高速検索と順序保持を両立できます
  2. Prune Logic: 外部状態が変化したら、useEffectで自動的に同期します
  3. アクセシビリティ: フォーカストラップとスクロールロックは別々の責務として実装します
  4. メタデータ駆動: 比較項目を配列で定義すると、拡張性が高まります

次のステップ

この実装パターンは、比較機能以外にも以下のようなケースで応用できます。

  • ショッピングサイトの商品比較
  • 不動産サイトの物件比較
  • サービス比較サイトの機能比較
  • プラン比較・料金表の実装

記事内で紹介したコードは、すべて実際に動作する実装です。
ぜひ参考にして、自分のプロジェクトで複数選択機能を実装してみてください。