# 機能設計書 18-Client Components

## 概要

本ドキュメントは、Next.js App RouterにおけるClient Componentsの設計を記述する。`'use client'` ディレクティブによるクライアントコンポーネントの指定機能であり、インタラクティブなUIを実現する。

### 本機能の処理概要

Client Components機能は、`'use client'` ディレクティブをファイル先頭に宣言することで、そのモジュール以下をクライアントサイドで実行されるコンポーネントとして指定する機能である。

**業務上の目的・背景**：Server Componentsがデフォルトであるapp/ディレクトリにおいて、ユーザーインタラクション（onClick、onChangeなど）やブラウザAPI（useState、useEffect等）を使用するコンポーネントを明示的に定義する必要がある。Client Componentsはクライアントバンドルに含まれ、ブラウザ上でハイドレーションされて動作する。

**機能の利用シーン**：フォーム入力処理、ボタンクリックイベント処理、状態管理を伴うUI、ブラウザAPI利用（geolocation、localStorage等）、サードパーティのクライアント専用ライブラリの使用時に利用される。

**主要な処理内容**：
1. `'use client'` ディレクティブの検出とClient Reference変換（ビルド時）
2. `isClientReference()` によるClient Component判定
3. サーバーサイドでのClient Reference生成（ClientPageRoot/ClientSegmentRoot）
4. Client Reference ManifestによるモジュールIDの管理
5. クライアントサイドでのハイドレーションとインタラクティブ化
6. Server ComponentからClient Componentへのpropsシリアライゼーション

**関連システム・外部連携**：React Flight（RSCプロトコル）、Webpack/Turbopack（クライアントバンドル生成）。

**権限による制御**：該当なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Client ComponentsはすべてのインタラクティブなUI要素に適用される基盤機能 |

## 機能種別

コンポーネント管理 / レンダリング制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| 'use client' | ディレクティブ | Yes | ファイル先頭に記述する宣言 | ファイルの最初の文（import前） |
| props | シリアライザブル | Yes | Server Componentから渡されるprops | シリアライズ可能な値 |

### 入力データソース

- ファイルシステム（`'use client'` ディレクティブ付きモジュール）
- Client Reference Manifest（ビルド時に生成）
- Server Componentからのprops

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| クライアントバンドル | JavaScript | Client Componentのコードを含むバンドルファイル |
| Client Reference | モジュール参照 | RSCペイロード内でのモジュール参照情報 |
| ハイドレーションされたDOM | DOM | インタラクティブなUI要素 |

### 出力先

- クライアントJavaScriptバンドルファイル
- ブラウザDOM

## 処理フロー

### 処理シーケンス

```
1. ビルド時: 'use client'ディレクティブ検出
   └─ バンドラがClient Referenceに変換
2. ビルド時: Client Reference Manifest生成
   └─ モジュールIDとチャンクの対応情報を記録
3. サーバーレンダリング時: isClientReference判定
   └─ $$typeof === Symbol.for('react.client.reference')
4. サーバーレンダリング時: ClientPageRoot/ClientSegmentRootでラップ
   └─ Client Componentのサーバーサイドレンダリング結果とClient Referenceを生成
5. 初回アクセス時: HTMLの配信
   └─ SSR結果としてのHTMLとClient Reference情報を含むRSCペイロード
6. クライアント: ハイドレーション
   └─ Client ComponentのJavaScriptを読み込みハイドレーション
7. クライアント: インタラクティブ化
   └─ イベントハンドラの有効化、useStateによるステート管理開始
```

### フローチャート

```mermaid
flowchart TD
    A['use client'ディレクティブ] --> B[ビルド: Client Reference変換]
    B --> C[Client Reference Manifest生成]
    C --> D[サーバーレンダリング]
    D --> E[isClientReference判定]
    E --> F[ClientPageRoot/ClientSegmentRootでラップ]
    F --> G[SSR HTML + RSCペイロード送信]
    G --> H[クライアント: JSバンドル読み込み]
    H --> I[ハイドレーション]
    I --> J[インタラクティブUI]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ディレクティブ宣言 | 'use client'はファイルの最初の文として記述する必要がある | Client Component定義時 |
| BR-02 | 境界伝搬 | 'use client'を宣言したモジュールからインポートされるすべてのモジュールもClient Component扱い | 常時 |
| BR-03 | propsシリアライズ | Server ComponentからClient Componentへのpropsはシリアライズ可能である必要がある | SC→CC境界 |
| BR-04 | バンドル包含 | Client Componentのコードはクライアントバンドルに含まれる | 常時 |
| BR-05 | SSRサポート | Client ComponentもSSR時にサーバーサイドでレンダリングされる | SSR時 |

### 計算ロジック

該当なし。

## データベース操作仕様

該当なし。Client ComponentはクライアントサイドAPIのみ使用可能。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ハイドレーションミスマッチ | SSR結果とクライアントレンダリング結果の不一致 | 開発時にコンソール警告を表示 |
| - | シリアライゼーションエラー | 非シリアライズ可能なpropsがSC→CC境界を越える | ランタイムエラー |
| - | レンダリングエラー | Client Component内の例外 | error.tsxバウンダリでキャッチ |

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- Client Componentのコードはクライアントバンドルに含まれるため、不必要なClient化を避けることが推奨される
- 'use client'の境界を適切に設定し、インタラクティブな部分のみをClient Componentにすることでバンドルサイズを最小化

## セキュリティ考慮事項

- Client Componentのコードはクライアントに送信されるため、機密情報を含めてはならない
- Server Componentから渡されたpropsもクライアントに公開される

## 備考

- Client ComponentからServer Componentをchildrenとして渡すことは可能（Compositionパターン）
- SSR時にはClient Componentもサーバーサイドでレンダリングされるが、ハイドレーション後にクライアントサイドの状態管理が有効になる

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | client-and-server-references.ts | `packages/next/src/lib/client-and-server-references.ts` | isClientReference関数（45-48行目）でClient判定の仕組みを理解 |

**読解のコツ**: `$$typeof === Symbol.for('react.client.reference')` がバンドラによって'use client'付きモジュールに付与されるマーカー。mod.defaultまたはmod自体のいずれかで判定される（46行目）。

#### Step 2: ビルド時のClient Reference変換

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | manifests-singleton.ts | `packages/next/src/server/app-render/manifests-singleton.ts` | getClientReferenceManifestでClient Componentのモジュール参照マップを管理 |

#### Step 3: サーバーサイドのClient Component処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create-component-tree.tsx | `packages/next/src/server/app-render/create-component-tree.tsx` | isClientComponent判定（741行目）とClientPageRoot/ClientSegmentRootラップ（768-896行目） |

**主要処理フロー**:
1. **741行目**: `const isClientComponent = isClientReference(layoutOrPageMod)` で判定
2. **768行目**: ページのClient ComponentはClientPageRootでラップ
3. **878行目**: セグメントのClient ComponentはClientSegmentRootでラップ

#### Step 4: クライアントサイドのハイドレーション

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | app-router.tsx | `packages/next/src/client/components/app-router.tsx` | クライアントサイドのRSCペイロード消費とハイドレーション |

### プログラム呼び出し階層図

```
ビルド時:
バンドラ (Webpack/Turbopack)
    |
    +-- 'use client' ディレクティブ検出
    |      └─ Client Reference変換 ($$typeof設定)
    |
    +-- Client Reference Manifest生成

サーバーレンダリング時:
createComponentTreeInternal
    |
    +-- isClientReference (client-and-server-references.ts)
    |
    +-- ClientPageRoot / ClientSegmentRoot
    |      └─ Server側でSSR + Client Reference埋め込み

クライアント:
app-router.tsx
    |
    +-- RSCペイロード消費
    +-- ハイドレーション
    +-- インタラクティブ化
```

### データフロー図

```
[入力]                          [処理]                        [出力]

'use client' モジュール ----> バンドラ変換 --------> Client Reference
                                                        |
Server Component props -----> シリアライゼーション --> RSCペイロード内参照
                                                        |
クライアントJSバンドル -----> ハイドレーション ------> インタラクティブDOM
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| client-and-server-references.ts | `packages/next/src/lib/client-and-server-references.ts` | ソース | Client Reference判定 |
| create-component-tree.tsx | `packages/next/src/server/app-render/create-component-tree.tsx` | ソース | SC/CC分岐とClientRoot生成 |
| manifests-singleton.ts | `packages/next/src/server/app-render/manifests-singleton.ts` | ソース | Client Reference Manifest管理 |
| app-router.tsx | `packages/next/src/client/components/app-router.tsx` | ソース | クライアントサイドルーター・ハイドレーション |
| app-render.tsx | `packages/next/src/server/app-render/app-render.tsx` | ソース | RSCレンダリング統合 |
