Next.js mixes server and client code, so managing state needs special care to keep data consistent and fast.
Why state management differs in Next.js
import { useState } from 'react'; // Client component state const [count, setCount] = useState(0); // Server component data fetching const data = await fetchData(); // Using React Server Components and client state together
Next.js uses React Server Components by default, so state hooks like useState only work in client components.
Data fetching can happen on the server, so state management often mixes server data and client state.
// Client component with state 'use client'; import { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> Count: {count} </button> ); }
// Server component fetching data export default async function Page() { const data = await fetch('https://api.example.com/data').then(res => res.json()); return <div>Data: {data.value}</div>; }
// Mixing server data and client state 'use client'; import { useState } from 'react'; export default function ClientComponent({ initialCount }) { const [count, setCount] = useState(initialCount); return <button onClick={() => setCount(count + 1)}>Count: {count}</button>; }
This is a simple Next.js client component that uses React's useState to manage a counter. It shows how client state works in Next.js.
'use client'; import { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); return ( <main style={{ padding: '1rem', fontFamily: 'Arial, sans-serif' }}> <h1>Simple Counter</h1> <button aria-label="Increase count" onClick={() => setCount(count + 1)} style={{ fontSize: '1.5rem', padding: '0.5rem 1rem', cursor: 'pointer' }} > Count: {count} </button> </main> ); }
Next.js uses React Server Components by default, so you must add 'use client' at the top of files that use client state.
Server components can fetch data before sending HTML to the browser, improving speed.
Client components handle interactive state like clicks or form inputs.
Next.js mixes server and client code, so state management splits between server data and client state.
Use 'use client' directive to enable client state hooks like useState.
Server components fetch data early, client components handle user interaction.