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

use client はどこに書くのか

use client はファイルの先頭に一度だけ書き、そこから下のツリーを Client Component にするためのディレクティブです。

#何のためのものか

App Router では、書いたコンポーネントは既定で Server Component です。サーバーの上だけで実行され、その JavaScript はブラウザに届きません。

ところが useStateonClick もブラウザがないと動きません。そこで「ここから先はブラウザにも送る」という線を引く必要があります。その線を引くのが use client です。

#どこに書くのか

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

'use client'

import { useState } from 'react'

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

このファイルを import した先も、さらにその先も、まとめて Client Component になります。境界は下方向にだけ伝わります。

#よくある誤解

誤解1 付けた方が安全そうだから全部に付ける

逆です。use client は「ブラウザに JavaScript を送る」という宣言なので、付けるほどページは重くなります。

置く場所は、ブラウザの機能が実際に必要な、いちばん葉に近いところです。

誤解2 子に付けたら親も Client になる

なりません。伝わるのは下方向だけです。Server Component が Client Component を呼ぶのは正しい形です。

誤解3 Client Component の中では Server Component を使えない

children として渡せば使えます。

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

Panel が Client Component でも、ItemList は Server Component のまま実行されます。Client の内側で import すると Client になりますが、children として受け取る場合は既に描画済みのものを差し込むだけだからです。

#境界を越えられないもの

Server から Client へ渡す props は、シリアライズできる必要があります。

渡せる渡せない
文字列・数値・真偽値関数
配列・プレーンオブジェクトクラスのインスタンス
Date・Map・SetSymbol
Server Component の要素(children)Node.js のオブジェクト

関数を渡そうとしたときのエラーが、初学者がいちばん最初にぶつかる壁です。

#実務では

EC の商品詳細ページなら、こうなります。

app/products/[id]/page.tsx      Server(DB から商品を取得)
├─ ProductInfo                   Server(ただ表示するだけ)
├─ ReviewList                    Server(ただ表示するだけ)
└─ AddToCartButton               Client('use client' はここだけ)

ページ全体に use client を付けると、商品情報もレビューも全部ブラウザに送られます。カートのボタンだけが Client であるべきです。

理解できたか試す

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

このコードはそのまま動きますか。動かない場合、どこを直すのが適切ですか。

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