//
Busque em todas as páginas da documentação
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Tipar useRef corretamente para referências de elementos DOM e contêineres de valores mutáveis. Entender a diferença entre refs DOM somente leitura e refs mutáveis, e quando usar cada uma.
// Ref de elemento DOM (somente leitura .current)
function TextInput() {
const inputRef = useRef<HTMLInputElement>(null);
const focusInput = () => {
inputRef.current?.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focar Input</button>
</div>
);
}// Ref mutável (gravável .current)
function Timer() {
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
const [count, setCount] = useState(0);
const start = () => {
if (intervalRef.current) return;
intervalRef.current = setInterval(() => {
setCount((c) => c + 1);
}, 1000);
};
const stop = () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
};
return (
<div>
<p>{count}</p>
<button onClick={start}>Iniciar</button>
<button onClick={stop}>Parar</button>
</div>
);
}useRef<HTMLInputElement>(null) cria um objeto ref com { current: HTMLInputElement | null }. Quando passado para um atributo ref JSX, o React gerencia a definição de .current para o nó DOM.ref é uma prop regular em vez de um atributo especial. Componentes de função podem aceitar ref diretamente em suas props sem forwardRef.null e tipifique de acordo: useRef<NodeJS.Timeout | null>(null).useRef. A diferença é se o React gerencia .current (ref DOM) ou você o gerencia sozinho (ref mutável).Armazenando o valor anterior:
function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T | undefined>(undefined);
useEffect(() => {
ref.current = value;
});
return ref.current;
}Padrão de callback de ref:
function MeasuredBox() {
const [height, setHeight] = useState(0);
const measuredRef = (node: HTMLDivElement | null) => {
if (node) {
setHeight(node.getBoundingClientRect().height);
}
};
return (
<div ref={measuredRef}>
<p>Esta caixa tem {height}px de altura</p>
</div>
);
}Ref de elemento de vídeo:
const videoRef = useRef<HTMLVideoElement>(null);
// Reproduzir/pausar
const togglePlay = () => {
if (videoRef.current?.paused) {
videoRef.current.play();
} else {
videoRef.current?.pause();
}
};HTMLDivElement, HTMLInputElement, HTMLButtonElement, HTMLFormElement, HTMLCanvasElement, HTMLVideoElement, SVGSVGElement.ReturnType<typeof setInterval> é portátil entre ambientes Node e navegador em vez de codificar NodeJS.Timeout ou number.forwardRef não é mais necessário. Componentes podem aceitar ref como uma prop regular: function Input({ ref }: { ref?: React.Ref<HTMLInputElement> }).inputRef.current sem uma verificação de nulo resultará em erro sob strictNullChecks. Sempre use encadeamento opcional (?.) ou uma guarda..current em uma ref DOM gerenciada pelo React não tem efeito. O React a sobrescreve durante a renderização.useRef<HTMLInputElement>(null!) (asserção não nula) remove a necessidade de verificações de nulo, mas oculta bugs potenciais se a ref for acessada antes da montagem.null quando o componente é desmontado. Sempre trate o caso null.| Abordagem | Prós | Contras |
|---|---|---|
useRef<T>(null) | Tratamento de nulo seguro e explícito | Requer verificações de nulo em todos os lugares |
useRef<T>(null!) | Nenhuma verificação de nulo necessária | Inseguro se acessado antes da montagem |
| Função de callback de ref | Executa na montagem/desmontagem, útil para medições | Mais complexo, dispara em cada renderização no React 18 |
React.createRef() | Compatível com componentes de classe | Cria uma nova ref a cada renderização em componentes de função |
ref como prop (React 19) | Não é necessário wrapper forwardRef | Disponível apenas no React 19+ |
ref JSX e o React gerencia .current (definindo-o para o nó DOM)..current sozinho (por exemplo, armazenando um ID de timer ou valor anterior).useRef. A diferença é quem escreve em .current.null porque o nó DOM não existe até que o componente seja montado.useRef<HTMLInputElement>(null) fornece o tipo HTMLInputElement | null, que corresponde a este ciclo de vida.const videoRef = useRef<HTMLVideoElement>(null);HTMLVideoElement como parâmetro de tipo.videoRef.current?.play() com encadeamento opcional.setInterval, que difere entre Node (NodeJS.Timeout) e navegadores (number).ReturnType<typeof setInterval> é portátil entre ambos os ambientes sem codificação fixa.ref: ref={(node) => { ... }}.null).ref é uma prop regular. Componentes podem aceitá-la diretamente:function Input({ ref }: { ref?: React.Ref<HTMLInputElement> }) { ... }forwardRef ainda funciona, mas não é mais necessário.inputRef.current será null antes da montagem.useRef<HTMLInputElement>(null!) para pular as verificações de nulo, você oculta esse bug.?.) ou uma guarda de nulo em código de produção..current durante a renderização.useRef<T | undefined>(undefined).useEffect atualiza ref.current após cada renderização, então o valor retornado está sempre um render atrás.null: (node: HTMLDivElement | null) => void.null, pois o callback dispara com null na desmontagem.HTMLDivElement, HTMLInputElement, HTMLButtonElement, HTMLFormElementHTMLCanvasElement, HTMLVideoElement, SVGSVGElementnull.Revisado por Chris St. John·Última atualização: 7 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥