Hook useRef
Armazene um valor mutável que persiste entre renderizações sem causar novas renderizações.
Busque em todas as páginas da documentação
Armazene um valor mutável que persiste entre renderizações sem causar novas renderizações.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Cartão de receita de referência rápida - pronto para copiar e colar.
// Variável de instância mutável
const renderCount = useRef(0);
renderCount.current += 1;
// Referência de elemento DOM
const inputRef = useRef<HTMLInputElement>(null);
inputRef.current?.focus();
// Armazena o valor anterior
const prevValue = useRef(value);
useEffect(() => { prevValue.current = value; });Quando usar isso: Você precisa acessar um elemento DOM diretamente, armazenar um valor mutável que não deve disparar novas renderizações ou acompanhar um valor anterior.
"use client";
import { useEffect, useRef, useState } from "react";
export function Stopwatch() {
const [elapsed, setElapsed] = useState(0);
const [running, setRunning] = useState(false);
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
useEffect(() => {
if (running) {
intervalRef.current = setInterval(() => {
setElapsed((prev) => prev + 10);
}, 10);
}
return () => {
if (intervalRef.current) clearInterval(intervalRef.current);
};
}, [running]);
const reset = () => {
setRunning(false);
setElapsed(0);
};
const minutes = Math.floor(elapsed / 60000);
const seconds = Math.floor((elapsed % 60000) / 1000);
const ms = Math.floor((elapsed % 1000) / 10);
return (
<div className="space-y-3">
<p className="text-3xl font-mono tabular-nums">
{String(minutes).padStart(2, "0")}:{String(seconds).padStart(2, "0")}.
{String(ms).padStart(2, "0")}
</p>
<div className="flex gap-2">
<button
onClick={() => setRunning((r) => !r)}
className="px-3 py-1 border rounded"
>
{running ? "Stop" : "Start"}
</button>
<button onClick={reset} className="px-3 py-1 border rounded">
Reset
</button>
</div>
</div>
);
}O que isso demonstra:
useRef para armazenar o ID do intervalo para que ele possa ser limpo posteriormenteReturnType<typeof setInterval> fornece o tipo correto para o ID do temporizadoruseRef retorna um objeto mutável com uma única propriedade .current.current não dispara uma nova renderizaçãouseState, não há função de configuração - você muta .current diretamente| Parâmetro | Tipo | Descrição |
|---|---|---|
initialValue | T | Valor inicial atribuído a .current |
| Retorno | Tipo | Descrição |
|---|---|---|
ref | { current: T } | Objeto ref mutável |
Focar um input na montagem:
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
return <input ref={inputRef} />;Acompanhar valor anterior:
function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T | undefined>(undefined);
useEffect(() => {
ref.current = value;
});
return ref.current;
}Armazenar o último callback (evita closures obsoletas):
const callbackRef = useRef(callback);
useEffect(() => {
callbackRef.current = callback;
});
// Use callbackRef.current em manipuladores de eventos ou temporizadoresMedir um elemento DOM:
const divRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (divRef.current) {
const { width, height } = divRef.current.getBoundingClientRect();
setSize({ width, height });
}
}, []);// Ref DOM - use `null` como valor inicial com tipo de elemento
const divRef = useRef<HTMLDivElement>(null);
// divRef.current é HTMLDivElement | null
// Ref mutável - passe o tipo como genérico
const countRef = useRef<number>(0);
// countRef.current é number
// Distinção: useRef<T>(null) cria RefObject<T> (somente leitura .current)
// useRef<T | null>(null) cria MutableRefObject<T | null>
// Para refs DOM, use o primeiro padrão; para valores mutáveis, use o segundoLer refs durante a renderização - Acessar ref.current durante a renderização (fora de useEffect ou manipuladores de eventos) pode fornecer resultados inconsistentes. Correção: Leia refs apenas em efeitos ou manipuladores de eventos.
Esperar novas renderizações na mutação - Atualizar ref.current não re-renderiza o componente. Correção: Se a UI deve atualizar, use useState em vez disso.
Ref nula na primeira renderização - Uma ref DOM é null até que o React a anexe após a primeira renderização. Correção: Acesse refs DOM dentro de useEffect ou após uma verificação de nulo.
Confusão entre ref e estado - Armazenar dados visíveis na UI em uma ref significa que a exibição nunca é atualizada. Correção: Use refs apenas para valores que não precisam ser exibidos ou que impulsionam efeitos colaterais.
Refs de callback vs. refs de objeto - Refs de objeto não podem notificá-lo quando o elemento muda (por exemplo, renderização condicional). Correção: Use uma ref de callback ref={(node) => { ... }} quando precisar reagir à anexação/desanexação.
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
useState | O valor deve disparar uma nova renderização quando muda | Você precisa de um contêiner mutável silencioso |
| Ref de callback | Você precisa executar código quando uma ref é anexada ou desanexada | Você só precisa de uma referência estável a um elemento |
document.getElementById | Fora do React (raro) | Dentro de componentes React - use refs em vez disso |
| Variável de nível de módulo | O valor é compartilhado entre todas as instâncias de componente | O valor deve ser por instância de componente |
Por que refs em vez de variáveis de módulo? Variáveis de nível de módulo são compartilhadas entre todas as instâncias de um componente. Refs são por instância - cada componente montado obtém seu próprio .current.
useRef armazena um valor mutável que persiste entre renderizações, mas não dispara novas renderizações quando atualizado.useState armazena um valor que dispara uma nova renderização quando atualizado através de sua função de configuração.useRef para valores que a UI não exibe; use useState para valores que a UI reflete.null até que o React a anexe após a primeira renderização.useEffect (que é executado após a montagem) ou atrás de uma verificação de nulo.// Ref DOM: use inicialização null, obtenha RefObject<T> (somente leitura .current)
const inputRef = useRef<HTMLInputElement>(null);
// Ref mutável: inclua null na união genérica
const countRef = useRef<number | null>(null);
// countRef.current é number | null (mutável).current muta o objeto no local; o React não tem como detectar essa mudança.ref.current = newValue.useState em vez disso.function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T | undefined>(undefined);
useEffect(() => {
ref.current = value;
});
return ref.current;
}useEffect é executado após a renderização.ref={(node) => { ... }} quando precisar executar código quando um elemento for anexado ou desanexado (por exemplo, renderização condicional).const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
useEffect(() => {
intervalRef.current = setInterval(tick, 1000);
return () => {
if (intervalRef.current) clearInterval(intervalRef.current);
};
}, []);ref.current durante a renderização (fora de useEffect ou manipuladores de eventos) pode fornecer resultados inconsistentes..current.const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
return <input ref={inputRef} />;null até a montagem, então acesse-a dentro de useEffect com encadeamento opcional.callbackRef.current em temporizadores ou ouvintes de eventos para sempre chamar a versão mais recente.Revisado por Chris St. John·Última atualização: 16 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥