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

useState を import できないエラー

実際に出るエラー

Error: You're importing a module that depends on `useState` into a React Server
Component module. This API is only available in Client Components. To fix, mark
the file (or its parent) with the `"use client"` directive.

Server Component のファイルから useState などのフックを import したときに出るビルドエラーです。

#何が起きているか

App Router のファイルは、既定で Server Component として解決されます。useState はブラウザ側の状態を扱う API なので、Server Component のモジュールからは import できません。

重要なのは、**エラーが出るのは「使った場所」ではなく「import したモジュール」**だという点です。エラー文も "importing a module that depends on useState" と書いています。自分では useState を書いていなくても、間接的に依存しているものを import しただけで同じエラーになります。

これは描画より前、モジュールを解決する段階で検出されます。だから next buildnext dev も、ページを開く前に止まります。

#原因はほぼこの3つ

1. 'use client' を書き忘れている

いちばん多い形です。

// app/counter/page.tsx
import { useState } from 'react'   // ← 先頭に 'use client' が無い

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

2. 'use client' の位置が間違っている

ファイルのいちばん先頭でなければ効きません。import の後ろに書いても無効です。コメントより前である必要はありませんが、import 文より前に置いてください。

3. import したライブラリが内部でフックを使っている

自分のコードにフックが1つも無いのに出る場合は、これです。UI ライブラリ、フォームライブラリ、アニメーションライブラリなどが該当します。

#最短の確認手順

  1. エラー文に出ているファイル名を開く
  2. 1行目が 'use client' かどうかを見る
  3. 違うなら、そのファイルは Server Component
  4. 自分のコードにフックが無い場合は、import 文を上から順に疑う

#直し方

推奨:フックを使う部品だけを切り出す

ページ全体に 'use client' を付けるのではなく、状態を持つ部分だけを別ファイルにします。

// components/Counter.tsx
'use client'

import { useState } from 'react'

export function Counter() {
  const [n, setN] = useState(0)
  return <button onClick={() => setN(n + 1)}>{n}</button>
}
// app/counter/page.tsx(Server Component のまま)
import { Counter } from '@/components/Counter'

export default async function Page() {
  const title = await getTitle()   // サーバー側でデータを取れる
  return (
    <>
      <h1>{title}</h1>
      <Counter />
    </>
  )
}

こうすると、ブラウザへ送られる JavaScript はカウンターの分だけで済みます。

ライブラリが原因の場合

そのライブラリを使う部分を、'use client' を書いた薄いファイルで包みます。

// components/Chart.tsx
'use client'

export { Chart } from 'some-chart-library'

#なぜページ全体に付けてはいけないのか

'use client' は「ここから下をブラウザにも送る」という宣言です。ページの先頭に書くと、そのページが import しているものすべてが対象になります。

  • 表示するだけの部分まで JavaScript がブラウザへ送られる
  • DB やサーバー専用の処理を、そのファイルから直接呼べなくなる

付けるほど重くなるので、置く場所はできるだけ葉に近い側です。

#開発中に出るのか

出ます。これは描画前の解決段階で検出されるので、next dev でもそのページに移動した時点で止まります。本番だけで出るタイプのエラーではありません。

#再発防止

  • フックを使うファイルは、作った瞬間に 'use client' を書く
  • 逆に、'use client' を書いたファイルには「ブラウザが必要な処理」しか置かない
  • 新しいライブラリを入れたら、Server Component から使えるかを最初に確かめる

#関連するエラー

windowdocument を Server Component で参照した場合は、ビルドではなく描画の段階で別のエラーになります。

ReferenceError: window is not defined

こちらは import では検出できないので、実際に描画されるまで出ません。

理解できたか試す

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

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

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