Aprenda / Frontend — Tailwind & Next.js

FundamentosAula 7 de 2014 min0% da trilha

Componentes de servidor vs. cliente

Por padrão tudo roda no servidor — "use client" é a exceção, não a regra.

No App Router, todo componente é Server Component por padrão. Ele roda no servidor, nunca manda seu próprio JavaScript pro navegador, e por isso pode fazer coisas que o navegador não devia fazer diretamente — ler um banco de dados, usar uma variável de ambiente secreta, chamar uma API interna.

Server Component (padrão, sem diretiva nenhuma)
// roda só no servidor — pode até acessar banco/arquivo direto
async function ListaDeProdutos() {
  const produtos = await buscarProdutosNoBanco();
  return (
    <ul>
      {produtos.map((p) => <li key={p.id}>{p.nome}</li>)}
    </ul>
  );
}

Quando você precisa de "use client"

Um componente só precisa da diretiva "use client" quando ele usa algo que só existe no navegador: useState, useEffect, onClick, localStorage, qualquer evento de interação.

Client Component — precisa de interatividade
"use client";

import { useState } from "react";

export function ContadorDeLikes({ inicial }: { inicial: number }) {
  const [likes, setLikes] = useState(inicial);
  return <button onClick={() => setLikes((n) => n + 1)}>❤ {likes}</button>;
}

Os dois convivem na mesma árvore

Um Server Component pode renderizar um Client Component como filho (o contrário — Client importando Server direto — não funciona). Na prática: busque o dado no servidor, passe como prop, e isole a interatividade num componente filho pequeno e marcado com "use client" — em vez de marcar a página inteira.

app/produtos/page.tsx
import { ContadorDeLikes } from "./contador-de-likes";

export default async function ProdutosPage() {
  const produtos = await buscarProdutosNoBanco(); // roda no servidor
  return (
    <ul>
      {produtos.map((p) => (
        <li key={p.id}>
          {p.nome} <ContadorDeLikes inicial={p.likes} /> {/* só esse pedaço vira JS no navegador */}
        </li>
      ))}
    </ul>
  );
}

Exercício

Um formulário de busca com um <input onChange> precisa de "use client"? E a página que lista os resultados da busca, que só recebe o termo e busca no banco?

Quiz rápido

No App Router, qual é o padrão quando nenhuma diretiva é escrita?
Quando um componente PRECISA de "use client"?