O Que São React Server Components?
RSC é um paradigma onde componentes React rodam exclusivamente no servidor e nunca são hidratados no cliente. Isso significa:
- Zero JavaScript enviado para o cliente (para esses componentes)
- Acesso direto a banco de dados, sistema de arquivos, variáveis secretas
- Sem hooks de estado (
useState,useEffect); eles não existem no servidor - Resultados em streaming para uma UI mais rápida
O Modelo Mental Correto
Pense assim:
Server Components → "Templates que buscam dados"
Client Components → "Ilhas de interatividade"
No Next.js 14+, tudo é Server Component por padrão. Você marca como cliente apenas o que precisa de interatividade.
Quando Usar Server Components ✅
// ✅ Buscar dados do banco/API diretamente
async function ProductList() {
const products = await db.product.findMany(); // acesso direto ao DB!
return (
<ul>
{products.map((p) => (
<li key={p.id}>{p.name} - R$ {p.price}</li>
))}
</ul>
);
}
// ✅ Usar variáveis de ambiente secretas
async function WeatherWidget() {
const data = await fetch(
`https://api.weather.com/v1?key=${process.env.WEATHER_SECRET_KEY}`
).then((r) => r.json());
return <div>Temperatura: {data.temp}°C</div>;
}
// ✅ Renderizar conteúdo estático / markdown
function BlogPost({ content }: { content: string }) {
return <div dangerouslySetInnerHTML={{ __html: content }} />;
}
Quando Usar Client Components ✅
"use client"; // marca como client component
// ✅ Estado interativo
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
// ✅ Efectos e subscriptions
function ThemeToggle() {
const { theme, setTheme } = useTheme(); // hook customizado
return <button onClick={() => setTheme(t => t === "dark" ? "light" : "dark")}>...</button>;
}
// ✅ Event handlers complexos
function SearchInput() {
const [query, setQuery] = useState("");
const debouncedSearch = useDebounce(query, 300);
// ...
}
O Anti-Pattern Mais Comum
O erro que mais vejo é marcar tudo como "use client" por precaução. Isso elimina todos os benefícios dos RSC:
// ❌ Não faça isso
"use client";
// Este componente não tem NENHUMA interatividade
// mas foi marcado como cliente desnecessariamente
export default async function BlogPage() {
const posts = await getPosts(); // Isso não funciona em client components!
return <PostList posts={posts} />;
}
A Regra de Ouro
Empurre o "use client" o mais abaixo possível na árvore de componentes. Um componente Server pode renderizar um Client Component como filho. O contrário NÃO é possível.
// ✅ Padrão correto: Server busca dados, Client adiciona interatividade
// app/blog/page.tsx (Server Component)
async function BlogPage() {
const posts = await getPosts(); // busca no servidor
return (
<div>
<h1>Blog</h1>
<CategoryFilter posts={posts} /> {/* Client Component */}
</div>
);
}
// components/CategoryFilter.tsx (Client Component)
"use client";
function CategoryFilter({ posts }: { posts: Post[] }) {
const [activeCategory, setActiveCategory] = useState("todos");
// filtra e renderiza os posts
}
Gostou do conteúdo?
Se você precisar de ajuda aplicando essas técnicas no seu projeto, estou disponível para consultoria.

Autor
Paulo Reducino
Desenvolvedor Frontend com 5+ anos de experiência em React, Next.js e TypeScript. Especialista em performance, SEO e acessibilidade. Atualmente na Vizuh (Londres, UK).
