O que é uma ref?
useRef cria um objeto { current: ... } que persiste entre renders e
que você pode mutar livremente. O diferencial: mudar ref.current NÃO provoca
um re-render. É o contrário de useState.
const ref = useRef(valorInicial);
ref.current; // você lê o valor
ref.current = outro; // você o muda (sem repintar)
Ela tem dois usos principais.
1) Referenciar um nó do DOM
Passando uma ref ao atributo ref de um elemento, o React coloca o nó real do DOM
em ref.current. Assim você pode fazer coisas imperativas como focar um input:
function Buscador() {
const inputRef = useRef(null);
return (
<div>
<input ref={inputRef} placeholder="Buscar…" />
<button onClick={() => inputRef.current.focus()}>Focar</button>
</div>
);
}
Quando o componente é montado, inputRef.current aponta para o <input> real, e
podemos chamar .focus(), .scrollIntoView(), etc.
2) Guardar um valor mutável que NÃO repinta
Às vezes você precisa lembrar um dado entre renders mas não quer que mudá-lo
repinte a interface: o id de um setInterval, o valor anterior de uma prop, um
contador interno... Isso vai em uma ref, não no estado.
function Render() {
const renders = useRef(0);
renders.current++; // conta renders SEM provocar outro render
return <p>Renders: {renders.current}</p>;
}
Estado vs. ref
useState |
useRef |
|
|---|---|---|
| Ao mudar o valor | repinta | não repinta |
| Para quê | dados que aparecem na UI | DOM e valores "nos bastidores" |
| Como se muda | com setX(...) |
mutando ref.current |
Regra prática: se o dado é exibido e deve aparecer atualizado, vai no estado. Se é um detalhe interno que a UI não precisa mostrar ao mudar, vai em uma ref. Quer mostrar o valor de uma ref na tela? Copie-o para o estado no momento adequado (por exemplo, ao clicar em um botão).