本文へ移動
verified onnext@16.3.3react@19
最終検証日 2026-08-27
Next.js道場

Client Component とは何か

Client Component は、ファイルの先頭に use client と書くことでブラウザにも送られる React コンポーネントです。

#いつ必要になるのか

判断は単純です。ブラウザにしかないものが必要かどうかだけを見ます。

必要なものClient にする
useState useReducer などの状態要る
useEffect要る
onClick onChange などのイベント要る
window document localStorage要る
ブラウザ専用のライブラリ要る
表示するだけ要らない
データを取ってきて並べるだけ要らない

迷ったら「押せるか」「変わるか」で考えてください。押せる/変わるならブラウザが必要です。

#書き方

ファイルのいちばん上、import より前に一度だけ書きます。

'use client'

import { useState } from 'react'

export function Counter() {
  const [n, setN] = useState(0)
  return <button onClick={() => setN(n + 1)}>{n}</button>
}

#サーバーでも動くことに注意

名前から「ブラウザだけで動く」と思いがちですが、違います。Client Component も、最初の表示のためにサーバー側で一度実行されます。

1. サーバーで実行 ──▶ HTML を作る(初回表示が速い)
2. ブラウザへ JavaScript が届く
3. ブラウザで実行 ──▶ 押せるようになる(hydration)

だから Client Component の中に window.innerWidth をそのまま書くと、手順1で落ちます。ブラウザ限定の処理は useEffect の中に置いてください。

**「Client Component = ブラウザだけ」ではなく「Client Component = ブラウザにも送られる」**と覚えるほうが正確です。

#境界は下にだけ伝わる

'use client' を書いたファイルから import したものは、すべて Client Component になります。逆はありません。親には影響しません。

Page(Server)
└─ Panel('use client')      ← ここから下が Client
   └─ Badge                    ← Client になる

だから、付ける位置が上へ行くほど、ブラウザへ送る JavaScript が増えます。

#大きくなってきたら children で逃がす

Client Component の中に重い表示を抱えたくなったら、import するのではなく children として外から渡します。渡されたものは境界に巻き込まれません。

// app/page.tsx(Server のまま)
export default async function Page() {
  const items = await db.item.findMany()
  return (
    <Panel>
      <ItemList items={items} />   {/* Server のまま */}
    </Panel>
  )
}

Panel の中で import { ItemList } と書くと、その瞬間に ItemList も Client になります。children で渡すか import するかで結果が変わるのがここです。

#受け取れる props には制限がある

Server から Client へ渡せるのは、値だけです。

  • 渡せる: 文字列・数値・配列・プレーンなオブジェクト・DateMapSet
  • 渡せない: 関数・クラスのインスタンス

関数を渡すとエラーになるので、ハンドラは Client Component の内側で定義します。

#よくある誤解

'use client' を付けたら、そのファイルはブラウザでしか動かない?

動きます。上に書いたとおり、初回はサーバーでも実行されます。

async にできない?

Next.js 16.3.3 ではビルドは通ります。「Client Component は async にできない」と書いてある記事は多いのですが、実際に試すと通ります。ただし読み込み中の表示が扱いにくくなるので、use フックか useEffect を使うほうが素直です。

迷ったら付けておけばいい?

逆です。付けるほどブラウザへ送る JavaScript が増えます。必要なところにだけ付けてください。

理解できたか試す

では、このコードはどうなりますか。

このファイルには use client がありません。どうなりますか。

この問題を解くこのテーマの問題 3