はじめに

本ドキュメントは、画面仕様書からReactコンポーネントを設計・実装するまでのフローを定義します。
6カテゴリのコンポーネント分類に基づき、一貫した設計判断を行うための指針を提供します。
最後に、これらの分類をAIに依頼するプロンプトをまとめます。

注記
本ガイドラインは「Next.js App Router + React Server Components」を前提とした設計体系であり、Pages Router や CSR 前提構成では同一の効果を保証しません。

目次

  1. 設計フロー概要
  2. コンポーネント分類
  3. 分類判定フロー
  4. カテゴリ別設計指針
  5. Server/Client Component判定
  6. 状態管理戦略
  7. View層とFoundation層の関係
  8. コンポーネントの分離設計:AIへの依頼プロンプト
  9. AIの応答サンプル
    Appendix:前提技術スタック

1. 設計フロー概要

コンポーネント設計は3つのフェーズで進行します。

フェーズ概要

Phase 目的 主な成果物
Phase 1: 構造設計 コンポーネントの洗い出しと分類 コンポーネント一覧、分類表
Phase 2: インターフェース設計 Props/State/イベントの定義 型定義ファイル、API設計書
Phase 3: 品質担保 バリデーション設計とテスト Storybook、テストコード

2. コンポーネント分類

本設計指針では、責務に基づく6カテゴリでコンポーネントを分類します。

カテゴリ 配置先 責務 基本境界
UI Components components/ui/ shadcn/ui準拠、ビジネスロジックなし Client Button, Input, Dialog
Form Components components/forms/ フォーム専用、バリデーション連携 Client FormField, DatePicker
Layout Components components/layouts/ レイアウト・構造のみ Server Header, Sidebar
Shared Components components/shared/ アプリ内再利用、軽いロジック 混在 UserAvatar, SearchBar
Feature Components features/{name}/components/ 機能固有、ビジネスロジック含む 混在 UserProfile, OrderForm
Route Components app/ ルーティング対応 Server page.tsx, layout.tsx

 

ディレクトリ構造

src/
├── app/                          # Route Components
│   ├── (auth)/
│   │   ├── login/page.tsx
│   │   └── layout.tsx
│   ├── dashboard/
│   │   ├── page.tsx
│   │   ├── loading.tsx
│   │   └── error.tsx
│   └── layout.tsx
│
├── components/
│   ├── ui/                       # UI Components (shadcn/ui)
│   │   ├── button.tsx
│   │   ├── input.tsx
│   │   └── dialog.tsx
│   ├── forms/                    # Form Components
│   │   ├── form-field.tsx
│   │   └── date-picker.tsx
│   ├── layouts/                  # Layout Components
│   │   ├── header.tsx
│   │   └── sidebar.tsx
│   └── shared/                   # Shared Components
│       ├── user-avatar.tsx
│       └── search-bar.tsx
│
└── features/                     # Feature Components
    └── users/
        ├── components/
        │   └── user-profile.tsx
        ├── hooks/
        │   └── use-user.ts
        └── actions/
            └── update-user.ts

3. 分類判定フロー

新規コンポーネントを作成する際は、以下のフローに従って分類を決定します。

判定基準

判定ポイント Yes の場合 具体例
ルーティング対応か? Route Components page.tsx, layout.tsx, error.tsx
shadcn/uiに存在するか? UI Components Button, Dialog, Tooltip など
フォーム入力専用か? Form Components バリデーション付きInput, DatePicker
レイアウト・構造のみか? Layout Components Header, Footer, Sidebar
ビジネスロジックを含むか? Feature Components API呼び出し、業務処理を含むコンポーネント
アプリ全体で再利用するか? Shared Components UserAvatar, LoadingSpinner

 

4. カテゴリ別設計指針

各カテゴリの設計フローと注意点を示します。

4.1 UI Components

責務: 汎用的なUI部品。ビジネスロジックを持たず、見た目と基本的なインタラクションのみを担当します。

設計ポイント:

  • shadcn/uiのコンポーネントを最優先で使用します
  • 拡張が必要な場合はCVA(class-variance-authority)でvariants追加します
  • forwardRefでref転送に対応します
  • aria属性を適切に設定してください
// components/ui/button.tsx の拡張例
const buttonVariants = cva(
  'inline-flex items-center justify-center rounded-md text-sm font-medium',
  {
    variants: {
      variant: {
        default: 'bg-primary text-primary-foreground hover:bg-primary/90',
        destructive: 'bg-destructive text-destructive-foreground',
        // カスタムvariant追加
        success: 'bg-green-600 text-white hover:bg-green-700',
      },
      size: {
        default: 'h-9 px-4 py-2',
        sm: 'h-8 px-3 text-xs',
        lg: 'h-10 px-8',
      },
    },
  }
)

4.2 Form Components

責務: フォーム入力に特化したコンポーネント。バリデーションとReact Hook Formとの連携を担当します。

設計ポイント:

  • Zodでスキーマを定義してください
  • React Hook FormのControllerまたはregisterと連携してください
  • エラーメッセージの表示ロジックを含めてください
  • アクセシビリティ(aria-invalid, aria-describedby)に対応してください
// components/forms/form-field.tsx の例
interface FormFieldProps {
  name: string
  label: string
  error?: string
  children: React.ReactNode
}

export function FormField({ name, label, error, children }: FormFieldProps) {
  const id = `field-${name}`
  const errorId = `${id}-error`

  return (
    <div className="space-y-2">
      <label htmlFor={id} className="text-sm font-medium">
        {label}
      </label>
      {children}
      {error && (
        <p id={errorId} className="text-sm text-destructive">
          {error}
        </p>
      )}
    </div>
  )
}

4.3 Layout Components

責務: ページのレイアウト構造を定義します。ビジネスロジックを持たず、配置のみを担当します。

設計ポイント:

  • 基本的にServer Componentとして実装します
  • childrenを活用してClient Componentを受け入れます
  • レスポンシブデザインに対応してください
  • 適切な位置にSuspense境界を配置してください
// components/layouts/sidebar.tsx の例
interface SidebarProps {
  children: React.ReactNode
}

export function Sidebar({ children }: SidebarProps) {
  return (
    <aside className="w-64 border-r bg-muted/40 p-4">
      <nav className="space-y-2">
        {children}
      </nav>
    </aside>
  )
}

4.4 Shared Components

責務: アプリ全体で再利用される共通コンポーネントです。軽いロジックは含めますが、特定機能に依存しません。

設計ポイント:

  • 特定のfeatureに依存しないようにしてください
  • Propsで必要なデータを受け取る設計にしてください
  • Server/Client境界は用途に応じて判断してください
// components/shared/user-avatar.tsx の例
interface UserAvatarProps {
  name: string
  imageUrl?: string
  size?: 'sm' | 'md' | 'lg'
}

export function UserAvatar({ name, imageUrl, size = 'md' }: UserAvatarProps) {
  const sizeClasses = {
    sm: 'h-8 w-8',
    md: 'h-10 w-10',
    lg: 'h-12 w-12',
  }

  return (
    <div className={cn('rounded-full bg-muted', sizeClasses[size])}>
      {imageUrl ? (
        <img src={imageUrl} alt={name} className="rounded-full" />
      ) : (
        <span>{name.charAt(0).toUpperCase()}</span>
      )}
    </div>
  )
}

4.5 Feature Components

責務: 特定機能のビジネスロジックを含むコンポーネントです。API呼び出し、状態管理、業務処理を担当します。

設計ポイント:

  • features/{機能名}/components/に配置してください
  • 状態管理戦略を明確に決定してください
  • Server Actionsを活用してミューテーションを実装してください
  • エラーハンドリングを適切に行ってください
// features/users/components/user-profile.tsx の例
'use client'

import { useSuspenseQuery } from '@tanstack/react-query'
import { useUser } from '../hooks/use-user'

export function UserProfile({ userId }: { userId: string }) {
  const { user } = useUser(userId)

  return (
    <div className="space-y-4">
      <h2 className="text-xl font-bold">{user.name}</h2>
      <p className="text-muted-foreground">{user.email}</p>
    </div>
  )
}

4.6 Route Components

責務: Next.js App Routerのルーティングに対応するコンポーネントです。ページの構成とデータフェッチを担当します。

設計ポイント:

  • 基本的にServer Componentとして実装してください
  • async/awaitで直接データフェッチを行ってください
  • loading.tsxerror.tsxを配置してください
  • generateMetadataでSEO対応してください
// app/users/[id]/page.tsx の例
import { Suspense } from 'react'
import { UserProfile } from '@/features/users/components/user-profile'
import { UserProfileSkeleton } from '@/features/users/components/user-profile-skeleton'

interface Props {
  params: { id: string }
}

export default function UserPage({ params }: Props) {
  return (
    <main className="container py-8">
      <Suspense fallback={<UserProfileSkeleton />}>
        <UserProfile userId={params.id} />
      </Suspense>
    </main>
  )
}

export async function generateMetadata({ params }: Props) {
  const user = await fetchUser(params.id)
  return { title: `${user.name}のプロフィール` }
}

5. Server/Client Component判定

コンポーネント作成時は、必ずServer/Client境界を判定してください。

判定基準

特性 Server Component Client Component
データフェッチ ✅ 直接async/await ❌ useQuery等が必要
useState/useEffect ❌ 使用不可 ✅ 使用可
イベントハンドラ ❌ 使用不可 ✅ 使用可
ブラウザAPI ❌ アクセス不可 ✅ アクセス可
初期バンドル ✅ 含まれない ❌ 含まれる
機密情報アクセス ✅ 安全 ❌ 露出リスク

境界設計のベストプラクティス

Client Componentは最小の葉に限定し、Server Componentで可能な限りラップしてください。

// ✅ 良い例:Server ComponentでClient Componentをラップ
// app/dashboard/page.tsx (Server Component)
async function DashboardPage() {
  const data = await fetchDashboardData()

  return (
    <div className="grid gap-4">
      {/* 静的な部分はServer Componentで */}
      <StatsCards data={data.stats} />

      {/* インタラクティブな部分のみClient Component */}
      <InteractiveChart data={data.chartData} />
    </div>
  )
}

6. 状態管理戦略

状態の種類に応じて適切なツールを選択してください。

判定順 状態の特性(質問) 採用ツール / 手法 スコープ 代表例
1 サーバー由来データか? TanStack Query サーバー由来 APIデータ、ユーザー情報
2 フォーム入力値か? React Hook Form + Zod フォーム 登録フォーム、検索フォーム
3 URL同期が必要か? nuqs(useQueryState) URL状態 検索クエリ、ページ番号
4 単一コンポーネント内で完結するか? useState ローカル モーダル開閉、タブ選択
5 複数コンポーネントで共有し、親子関係が近いか? 状態引き上げ(Props drilling) 親子間共有 親子間フィルター
6 複数コンポーネントで共有し、親子関係が遠いか? Context 画面内共有 テーマ、言語設定
7 アプリ全体で利用するか? Zustand グローバル 認証情報、通知

7. View層とFoundation層の関係

コンポーネントは大きくView層Foundation層に分かれます。データフローは一方向(View → Foundation)を維持してください。

8. コンポーネントの分離設計:AIへの依頼プロンプト

要件をもとに、コンポーネント分類を自動で行うAIプロンプトを整備しています。

AIは、必要となる各コンポーネントの一覧と、さらにその後続のコンポーネント作成に必要となるAIへの依頼プロンプトを出力します。

プロンプト使用時は、「## インプット情報」の{}で囲まれた箇所を具体的な要件に置換してからAIに投入します。コンポーネントの分離設計は複雑タスクですので、使用できる最上級の高級LLMモデルの使用を推奨します。

AI_request_prompt

9. AIの応答サンプル

ECサイト管理画面の注文管理機能について、ワイヤーフレームと機能要件からReact/Next.js App Router向けのコンポーネント分離設計をAIに依頼したサンプルです。Claude Codeでの試行結果を添付しています。

AI_request_sample1_ClaudeCode

AI_response_sample

まとめ

本ガイドラインの核心は「責務に基づく6カテゴリ分類」と「Server/Client境界の最小化」です。画面仕様書を受け取ったら、まず全コンポーネントを洗い出して分類し、View層(Feature/Route)にビジネスロジックを集約、Foundation層(UI/Form/Layout/Shared)はProps経由の純粋な表示に徹することで、保守性と再利用性を両立させましょう。迷ったときは判定フローに立ち返り、チェックリストで漏れを防ぐことが品質担保の鍵となります。


Appendix:前提技術スタック

レイヤ 技術 / ライブラリ 採用理由 / 前提
フレームワーク Next.js(App Router) Server / Client Component 分離、RSC、Server Actions を前提とした設計
言語 TypeScript Props / State / API の型安全性を担保するため必須
UI基盤 shadcn/ui + Radix UI アクセシビリティ準拠・Headless UI 前提、UI Components の基盤
スタイリング Tailwind CSS コンポーネント粒度での責務分離とデザイン一貫性の確保
Variants管理 class-variance-authority(CVA) UI Components の variant / size 拡張を標準化
フォーム管理 React Hook Form パフォーマンスと非制御入力前提のフォーム設計
バリデーション Zod フォーム・Server Actions・型定義
サーバー状態 TanStack Query Suspense前提のデータフェッチとキャッシュ管理
URL状態管理 nuqs URL = State を前提とした検索・ページング設計
グローバル状態 Zustand アプリ全体に影響する最小限の状態管理
ローカル共有状態 React Context 画面内限定・疎結合な状態共有用途
テスト(UI) Storybook コンポーネント単位の品質担保
テスト(ロジック) Testing Library / Vitest 振る舞いベースのテストを前提
データ取得 fetch / Server Actions Route / Feature にビジネスロジックを集約
AI支援 高性能LLM(Claude / GitHub Copilot等) コンポーネント分離・設計補助を前提とした利用