Can you explain React Server Components and when I should use them?
**React Server Components (RSC)** are a new paradigm that lets you render components on the server, sending only the HTML result to the client. Here's what you need to know:
Key Benefits
1. **Zero client-side JavaScript** for server components — they never ship JS to the browser
2. **Direct database/API access** without building REST endpoints
3. **Automatic code splitting** — client components are lazy-loaded by default
4. **Streaming** — the server can progressively send rendered HTML
When to Use Server Components
Use them when your component:
- Fetches data from a database or API
- Accesses server-only resources (filesystem, env variables)
- Renders large dependencies (markdown parsers, syntax highlighters)
- Doesn't need interactivity (no useState, onClick, etc.)
When to Use Client Components
Use `'use client'` when your component:
- Uses React hooks (useState, useEffect, useContext)
- Needs browser APIs (localStorage, window, navigator)
- Has event handlers (onClick, onChange)
- Uses third-party libraries that depend on client-side state
Show me an example of a Server Component that fetches data.
Here's a practical example of a Server Component that fetches data directly:
// app/users/page.tsx — This is a Server Component by default
import { db } from '@/lib/database'
interface User {
id: string
name: string
email: string
role: 'admin' | 'member'
}
export default async function UsersPage() {
// Direct database query — no API route needed!
const users = await db.query<User>(`
SELECT id, name, email, role
FROM users
ORDER BY created_at DESC
LIMIT 50
`)
return (
<div className="space-y-4">
<h1>Team Members</h1>
{users.map((user) => (
<UserCard key={user.id} user={user} />
))}
</div>
)
}
function UserCard({ user }: { user: User }) {
return (
<div className="rounded-lg border p-4">
<h3 className="font-semibold">{user.name}</h3>
<p className="text-muted">{user.email}</p>
<span className="badge">{user.role}</span>
</div>
)
}What about mixing Server and Client components together?
Great question! The key pattern is **composition** — Server Components can render Client Components as children, but not the other way around.
Here's the mental model:
// app/dashboard/page.tsx — Server Component
import { db } from '@/lib/database'
import { DashboardChart } from './chart' // Client Component
import { FilterPanel } from './filters' // Client Component
export default async function DashboardPage() {
// This runs on the server
const metrics = await db.getMetrics()
return (
<div>
{/* Pass server data to client components as props */}
<FilterPanel />
<DashboardChart data={metrics} />
{/* This static part stays on the server */}
<footer>
<p>Last updated: {new Date().toISOString()}</p>
</footer>
</div>
)
}// app/dashboard/chart.tsx — Client Component
'use client'
import { useState } from 'react'
import { BarChart } from 'recharts'
export function DashboardChart({ data }: { data: Metric[] }) {
const [timeRange, setTimeRange] = useState('7d')
const filtered = data.filter(d =>
isWithinRange(d.date, timeRange)
)
return (
<div>
<select onChange={e => setTimeRange(e.target.value)}>
<option value="7d">Last 7 days</option>
<option value="30d">Last 30 days</option>
</select>
<BarChart data={filtered} />
</div>
)
}Cortex may produce inaccurate information. Verify important facts independently.