RSC
Overview
Historically, all React components ran in the browser (Client-Side Rendering). This meant the browser had to download all the JavaScript, execute it, and then fetch data, leading to slow initial loads. React Server Components (RSC), introduced in React 18 and perfected in frameworks like Next.js App Router, allow components to render exclusively on the Server. Server Components never send their JS bundle to the browser, and they can connect directly to databases without an API layer.
Syntax
By making the component `async`, we can `await` data right inside the body. The server generates pure HTML and sends it to the browser, resulting in instant page loads and zero client-side JavaScript overhead.
// This component runs ONLY on the server.
// No JS is sent to the client. No useState, no useEffect allowed.
// It can be async and fetch data directly!
export default async function ProductList() {
// Direct database call! No need for fetch() or API routes.
const products = await db.query('SELECT * FROM products');
return (
<ul>
{products.map(p => <li key={p.id}>{p.name}</li>)}
</ul>
);
}Common Pitfalls
- Trying to use `useState`, `useEffect`, or `onClick` inside a Server Component. It will crash because those require a browser environment to function.
Interview Tips
- Understand the golden rule: Use Server Components for data fetching and heavy rendering. Use Client Components for Interactivity (buttons, forms, state, hooks).
Real-World Example
A heavy markdown parser. If it's a Server Component, the massive parser library stays on the server, keeping the client bundle tiny.
import { parseMarkdown } from 'heavy-markdown-parser'; // Huge library!
export default async function Article({ content }) {
// Parsing happens on the server. The client only receives the final HTML.
const html = await parseMarkdown(content);
return <div dangerouslySetInnerHTML={{ __html: html }} />;
}