gotchajavascriptnextjsMajor
Next.js: 'use client' directive needed for hooks and interactivity
Viewed 0 times
Next.js 13+ with App Router
use clientserver componentsclient componentsNext.js 13App RouteruseState server
browsernodejs
Error Messages
Problem
Using useState, useEffect, onClick, or any interactivity in a Next.js 13+ App Router component fails with Error: useState only works in Client Components. Add the 'use client' directive. By default, all components are Server Components.
Solution
Add 'use client' at the top of files that need interactivity:
// This file uses hooks — must be a client component
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
// Server Components (default) can:
// - Fetch data directly (async/await)
// - Access backend resources
// - Keep secrets server-side
// - Reduce client bundle size
// Pattern: Server Component wraps Client Component
// page.tsx (Server — fetches data)
export default async function Page() {
const data = await fetchData();
return <InteractiveList data={data} />; // passes data down
}
// InteractiveList.tsx ('use client' — handles interaction)
// This file uses hooks — must be a client component
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
// Server Components (default) can:
// - Fetch data directly (async/await)
// - Access backend resources
// - Keep secrets server-side
// - Reduce client bundle size
// Pattern: Server Component wraps Client Component
// page.tsx (Server — fetches data)
export default async function Page() {
const data = await fetchData();
return <InteractiveList data={data} />; // passes data down
}
// InteractiveList.tsx ('use client' — handles interaction)
Why
Next.js App Router uses React Server Components by default. Server Components render on the server only — they can't use browser APIs, hooks, or event handlers. 'use client' marks the boundary where client-side JavaScript begins.
Gotchas
- 'use client' must be at the very top of the file, before imports
- A Client Component can import Server Components only as children (props.children)
- Server Components can import and render Client Components
- Don't put 'use client' on every component — push it as far down the tree as possible
Code Snippets
Client Component in Next.js App Router
'use client'; // MUST be first line
import { useState } from 'react';
export function Toggle() {
const [on, setOn] = useState(false);
return <button onClick={() => setOn(!on)}>{on ? 'ON' : 'OFF'}</button>;
}Context
When using React hooks or event handlers in Next.js 13+ App Router
Revisions (0)
No revisions yet.