Server Components
React Server Components (RSC) let you render components on the server. They reduce the JavaScript sent to the client and improve performance.
Server vs Client Components
Server components run only on the server. They can access databases, file systems, and secrets directly.
Client components run in the browser and can use state, effects, and event handlers.
// Server component (default in Next.js App Router)
async function ProductList() {
const products = await db.query("SELECT * FROM products");
return (
<ul>
{products.map((p) => <li key={p.id}>{p.name}</li>)}
</ul>
);
}
"use client";
function AddToCartButton({ productId }) {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Add ({count})</button>;
}
The “use client” Directive
Place "use client" at the top of a file to mark it as a client component. Without it, components are server components by default.
"use client";
import { useState } from "react";
export default function Counter() {
const [val, setVal] = useState(0);
return <button onClick={() => setVal(val + 1)}>{val}</button>;
}
When to Use Which
- Server components — data fetching, accessing backend resources, large dependencies that don’t need client JS
- Client components — interactivity, browser APIs, state, effects, event handlers
Benefits
- Less JavaScript shipped to the client
- Direct access to data sources without API layers
- Automatic code splitting at the component boundary
- Improved initial page load and SEO
Combining Them
Server components can import and render client components.
// ServerComponent.jsx (server)
import ClientButton from "./ClientButton";
export default async function Page() {
const data = await fetchData();
return <ClientButton initialData={data} />;
}
Pass serializable props from server to client components.
Best Practices
- Default to server components — only add
"use client"when needed - Keep client components small and at the leaves of the tree
- Pass server-fetched data as props to client components
- Never import server-only code in client components
- Use
"use server"for server actions in form handling
Common Mistakes
- Adding
"use client"to entire pages instead of individual interactive components - Trying to use
useStateoruseEffectin a server component - Importing server-only modules in client components
- Passing non-serializable props (functions, class instances) from server to client
- Fetching data in client components when server components could handle it