DevPath · Aprenda a programar ESPTEN

useEffect, useRef e efeitos

useEffect: efeitos colaterais

Além do render

Um componente, em essência, calcula JSX a partir de props e estado. Mas às vezes você precisa fazer algo que não é calcular a interface: assinar um evento do navegador, iniciar um temporizador, mudar o título da aba, conversar com uma API... Isso é chamado de efeito colateral (side effect), porque afeta algo de fora do componente.

Essas ações não devem acontecer durante o render (o render deve ser puro e pode ser executado várias vezes). Para isso existe o hook useEffect: ele diz "execute este código depois de pintar, para sincronizar com algo externo".

function Titulo() {
  const [n, setN] = useState(0);

  useEffect(() => {
    document.title = "Clicado " + n + " vezes";
  });

  return <button onClick={() => setN(n + 1)}>Clicar</button>;
}

useEffect recebe uma função (o efeito) que o React executa após renderizar.

O array de dependências

O segundo argumento de useEffect é um array que controla quando o efeito é executado novamente:

// 1) Sem array: a CADA render
useEffect(() => { /* ... */ });

// 2) Array vazio []: apenas UMA vez, ao MONTAR o componente
useEffect(() => { /* ... */ }, []);

// 3) Com dependências: ao montar e toda vez que alguma delas MUDAR
useEffect(() => { /* ... */ }, [userId]);

Regra de ouro: inclua nas dependências todo valor reativo (props, estado) que você use dentro do efeito. Se você omitir, vai trabalhar com dados velhos.

A função de limpeza

Muitas assinaturas precisam ser desfeitas: um temporizador precisa ser parado, um listener precisa ser removido. Para isso, o efeito pode retornar uma função de limpeza. O React a executa antes de reexecutar o efeito e ao desmontar o componente.

function Relogio() {
  const [seg, setSeg] = useState(0);

  useEffect(() => {
    const id = setInterval(() => setSeg((s) => s + 1), 1000);
    return () => clearInterval(id); // limpeza: para o intervalo
  }, []);

  return <p>{seg} s</p>;
}

Sem essa limpeza, o intervalo continuaria vivo após desmontar o componente: um vazamento de recursos (e possíveis erros). A limpeza evita assinaturas duplicadas e deixa o sistema como estava.

Enquanto você renderiza, pense: "o que precisa ser conectado?" (o efeito) e "o que precisa ser desconectado?" (a limpeza).

Coloque isto em prática

O DevPath é um curso prático: aqui você lê a teoria; no app você a coloca em prática com exercícios que rodam de verdade, offline.

Comece grátis no app →
Carregar dados com useEffect →