Server Components no React: como funcionam e por que usar no seu projeto

Server Components no React: como funcionam e por que usar no seu projeto

“`html





Server Components no React — como funcionam


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.

Técnico e didático
Fluxo servidor → cliente
Limitações e trade-offs
Boas práticas

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.

Tradução prática: você decide onde o código faz sentido — no servidor para lógica e dados,
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.

Por que isso ajuda: ao mover render e dados para o servidor, você reduz o custo
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>
  );
}
O ponto central: o Server Component entrega a página com dados; o Client Component
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.

Quer continuar aprofundando?

Se você curte desempenho e arquitetura no React, vale a pena ler os próximos posts para consolidar
conceitos e boas práticas de renderização e separação de responsabilidades.



“`