Capítulo 06: Acesso ao DOM e Valores Persistentes com useRef e useId
Especialização Frontend com React & TypeScript • React 19, Hooks, Estado Global e Next.js
🗺️ Mapa Conceitual do Tópico
flowchart TD
REF["useRef(valorInicial)"] --> PERSIST["Objeto { current: valor } mantido em memória"]
PERSIST --> MUTATE["Mutação: ref.current = novoValor"]
MUTATE --> NO_RENDER["Zero Re-render! O componente continua inalterado"]
🏛️ 1. O Hook useRef: Estado Mutável Silencioso
Diferente do useState, alterar a propriedade .current de um useRef não dispara uma re-renderização. Ele atua como uma gaveta de valores arbitrários que persistem por todo o ciclo de vida do componente:
- Manipulação Imperativa do DOM: Manter referência física a inputs, canvas, vídeos e nós nativos.
- Armazenamento de Identificadores: Reter IDs de timers (
setTimeout), instâncias de WebSockets ou instâncias de bibliotecas externas (Chart.js, Mapbox).
🆔 2. O Hook useId e Acessibilidade (A11y)
O Hook useId gera identificadores únicos e estáveis para vincular atributos HTML de formulários (htmlFor do <label> com o id do <input>).
- Compatibilidade com SSR: Gera identificadores sincronizados deterministicamente entre o HTML renderizado no servidor e a hidratação no cliente, prevenindo erros de incompatibilidade de markup.
📊 3. Matriz Comparativa: useState vs useRef
| Aspecto de Engenharia | useState |
useRef |
|---|---|---|
| Dispara Re-renderização? | ✅ Sim, enfileira novo ciclo Fiber | ❌ Não, mutação puramente síncrona |
| Acesso ao Valor | Através da variável retornada | Através da propriedade .current |
| Momento de Atualização | Assíncrono no próximo render | Imediato e síncrono em memória |
| Caso de Uso Primário | Dados que determinam a interface visual | Elementos de DOM, timers e flags |
⚠️ 4. Armadilhas Comuns e Anti-Padrões de Produção
- Leitura/Escrita de
ref.currentDurante a Renderização: Ler ou escrever emref.currentno corpo principal da função (fora de handlers ouuseEffect) torna o componente impuro e quebra a renderização concorrente do React 19. - Usar
useRefpara Substituir o Estado: Usarrefpara armazenar textos de inputs controlados faz com que a interface visual não se atualize quando os dados mudam.
💡 5. Diretrizes de Engenharia (Meta & React Docs)
- Utilize Tipagem Estrita em Nós do DOM: Inicialize refs de DOM como
useRef<HTMLInputElement>(null), garantindo acesso aos métodos nativos via autocompletion seguro. - Nunca use
useIdpara Chaves de Listas:useIdfoi criado para vincular atributos de acessibilidade, não para atuar comokeyem iterações de arrays.
💻 6. Demonstração Arquitetural do Conceito
// AutoFocusInput.tsx - Manipulação imperativa segura
import React, { useRef, useId, useEffect } from "react";
export function AutoFocusInput() {
const inputId = useId();
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
return (
<div>
<label htmlFor={inputId}>Busca Imediata:</label>
<input id={inputId} ref={inputRef} type="text" placeholder="Foco automático..." />
</div>
);
}
📋 7. Cheat-Sheet: Casos de Uso do useRef
- ✅ Foco automático em inputs modais.
- ✅ Medição de dimensões físicas (
ref.current.getBoundingClientRect()). - ✅ Cancelamento de timers (
clearTimeout(timerRef.current)). - ✅ Armazenamento do valor anterior de uma prop (Previous Value Pattern).
🔍 8. Diagnóstico de Performance & React DevTools Profiler
Auditoria de referências persistentes:
- Mutação Silenciosa: Alterar
ref.currentnão registra nenhum commit no Profiler do React, comprovando que a operação é invisível para a árvore Fiber. - IDs Determinísticos: Verifique na árvore DOM renderizada se os atributos
aria-labelledbyeidcompartilham o mesmo prefixo estável (ex::r0:).
🧪 9. Casos de Teste e Cenários de Borda Recomendados
- 🔍 Acesso Pré-Montagem: Certifique-se de que o código trata
if (ref.current)defensivamente antes de invocar métodos de DOM. - 🔍 Conflito de IDs em Múltiplas Instâncias: Renderize 10 instâncias do mesmo componente e valide a unicidade estrita de cada
useId. - 🔍 Controle de Foco com Teclado: Valide a transição de foco para modais com leitores de tela ativados.