“`html
React • Rendering • Performance
Server Components no React: como funcionam na prática
Server Components mudam o modelo mental do React: ao invés de “montar tudo no cliente”, você escolhe
o que renderiza no servidor e o que vira JavaScript no navegador. Entenda o fluxo, as regras e o impacto
no bundle.
1) O que são Server Components (e o que muda)
No React moderno, a renderização não é necessariamente “tudo no browser”. Server Components
são componentes que rodam no servidor durante o render. Eles podem buscar dados, ler recursos do ambiente
e produzir HTML/React tree para ser entregue ao cliente.
A diferença principal é: enquanto componentes tradicionais (geralmente chamados de Client Components)
precisam virar JavaScript executando no navegador, Server Components não precisam
(em regra) entrar no bundle do cliente.
e no cliente apenas quando há necessidade de interatividade (estado, eventos, efeitos).
-
Server Components: executam no servidor, podem usar recursos server-side e
não carregam JavaScript correspondente para o cliente. -
Client Components: executam no navegador e precisam de JavaScript; normalmente recebem
interatividade (eventos) e lógica de UI baseada em estado. -
Importação determina fronteira: ao importar um componente, você atravessa regras de onde
ele pode rodar.
2) O fluxo de renderização: do servidor ao cliente
Pense no pipeline como uma entrega incremental de estrutura e conteúdo. O servidor resolve Server Components,
produz a árvore/resultado renderizável e envia ao cliente. Onde houver Client Components (marcados com
diretiva), o cliente passa a montar e habilitar interatividade para aquela parte.
Em termos conceituais, o fluxo fica assim:
-
O servidor renderiza Server Components (incluindo consultas de dados) e gera o que deve
aparecer na tela. - As partes que exigem interatividade ficam em Client Components.
-
O cliente recebe a UI já “pronta” em grande parte, e apenas as áreas com Client
Components passam por hidratação/montagem com JavaScript.
Resultado típico: menos JavaScript no navegador, mais rapidez para exibir conteúdo e uma
estratégia melhor de performance quando a UI depende de dados do servidor.
de “carregar, executar e hidratar” no client.
3) Regras essenciais: o que pode e o que não pode
As regras são simples: elas existem para manter a separação entre execução no servidor e no cliente.
Quando você quebra essas regras, o sistema acusa e evita inconsistências.
3.1) Marcação de Client Components
Um arquivo que precisa de interatividade normalmente começa com a diretiva
"use client". Isso “puxa” o componente para o cliente.
3.2) Implicações para imports
Se um Server Component importa um Client Component, a parte interativa vira um “pedaço” executado no
navegador. Já o inverso costuma ser problemático: um Client Component não deve depender de coisas
exclusivas do servidor.
3.3) Estado, eventos e efeitos
Onde há eventos (onClick), estado (useState),
ciclo de vida/effects (useEffect), isso é terreno de Client Components.
3.4) A fronteira muda o desenho
Em vez de “componente gigante com tudo”, você separa por responsabilidade:
dados e render estático no servidor; interatividade no cliente.
4) Um exemplo realista: dados no servidor, botão no cliente
A ideia é simples: buscar dados no Server Component e renderizar uma UI. Quando precisar de
interatividade (por exemplo, um botão com estado), você delega para um Client Component.
// app/page.tsx (Server Component por padrão)
import { VoteWidget } from "./vote-widget";
async function getPost() {
// Exemplo: buscar no banco / API (server-side)
return { id: 123, title: "Server Components no React" };
}
export default async function Page() {
const post = await getPost();
return (
<main>
<h1>{post.title}</h1>
{/* A interatividade fica no Client Component */}
<VoteWidget postId={post.id} />
</main>
);
}
// app/vote-widget.tsx (Client Component)
"use client";
import { useState } from "react";
export function VoteWidget({ postId }: { postId: number }) {
const [votes, setVotes] = useState<number>(0);
const [busy, setBusy] = useState<boolean>(false);
async function handleVote() {
setBusy(true);
try {
// Exemplo: chamar endpoint / action para atualizar voto
// (fica aqui porque depende de evento e estado no client)
await fetch(`/api/posts/${postId}/vote`, { method: "POST" });
setVotes(votes + 1);
} finally {
setBusy(false);
}
}
return (
<section>
<p>Votos: {votes}</p>
<button
onClick={handleVote}
disabled={busy}
>
{busy ? "Enviando..." : "Votar"}
</button>
</section>
);
}
cuida apenas da parte que precisa responder ao usuário.
Fechando: checklist para usar Server Components com segurança
Se você quiser aplicar isso em um projeto real, o que mais funciona é manter a fronteira nítida.
Um checklist rápido:
- Comece pelo servidor: render estático e busca de dados tendem a ficar melhores em Server Components.
-
Traga o cliente só quando necessário: se não há estado/eventos/effects, evite
"use client". - Separe por responsabilidade: componente grande com tudo geralmente piora o custo e a manutenção.
- Otimize props: Client Components recebem o que precisam (ex.: IDs e dados serializáveis), sem acoplar na camada server.
- Revise o impacto no bundle: o ganho aparece quando menos código precisa ir para o navegador.
Critério prático: se a lógica faz sentido como parte da “montagem da tela” com dados do servidor,
provavelmente é Server Component. Se depende diretamente de interação do usuário, é Client Component.
“`
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!