O que é useState
?
O useState
é hook do react, que de forma uma simples funciona como a memória do seu componente para os dados que, quando alterados , devem fazer o componente renderizar novamente.
Funciona assim:
- Você declara uma variável de estado e uma função pra atualizar ela
- Quando você usar essa função para mudar algum valor, o React vai ver e redesenhar esse “pedaço da tela”
Um exemplo básico:
import React, { useState } from "react";
function Counting() {
const [counter, setCounter] = useState(0);
const handleClick = () => {
setCounter(counter + 1); // Quando isso roda, o número na tela muda.
};
return (
<div>
<p>Cliques: {counter}</p>
<button onClick={handleClick}>Clique Aqui</button>
</div>
);
}
Se você só mudar uma variável normal do JS, o React nem fica sabendo, a tela vai continua estática. O useState
é o que trás a reatividade pro componente conectando a mudança de dados com a atualização da interface.
Uma coisa que eu demorei a entender é: Quando você atualiza algum estado, tipo setCounter(counter + 1)
, o counter
não muda instantaneamente. O React agenda uma atualização. Se em algum código você precisar do valor anterior pra calcular o novo, eu acho que o ideial seria usar: setCounter(prevCount => prevCount + 1)
O que é useRef
?
O useRef
é hook do react que também memoriza dados entre renderizações, mas a pricipal diferença é que mudar um ref
Não faz o componente renderizar de novo
Funciona assim:
- Você declara uma
ref
comuseRef()
, passando um valor inicial se quiser (tipouseRef(0)
pra um contador interno, ouuseRef(null)
se for pra “grudar” num elemento da tela - “Pra pegar ou mudar o valor que tá dentro da
ref
, você sempre vai usar a propriedade.current
dela (ex:ref.current = 'novo valor'
ouconsole.log(ref.current)
)
Importante: ao usar
useRef
para referenciar um elemento DOM (ex:inputRef
), a propriedadeinputRef.current
só será preenchida com o nó DOM após a montagem e renderização inicial do componente. Por isso, o acesso ainputRef.current
para manipulação DOM frequentemente ocorre dentro de um useEffect
Um exemplo básico:
import React, { useRef, useEffect } from "react";
function Input() {
const inputRef = useRef(null);
useEffect(() => {
// Quero que o input já venha focado quando a tela carregar
inputRef.current.focus();
}, []);
const showValue = () => {
alert(`You typed: ${inputRef.current.value}`); // Pega o valor diretamente do DOM via ref
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Auto-focus here!" />{" "}
{/* Linka a ref ao input */}
<button onClick={showValue}>Show Value</button>
</div>
);
}
useState vs useRef`
Quando Usar? | useState | useRef |
---|---|---|
Preciso que a tela atualize quando o valor mudar? | SIM! É o pilar dele. | NÃO. A mudança é silenciosa pra UI. |
Quero mexer em um elemento DOM diretamente? | Não é pra isso. | SIM! Focar input, tocar vídeo, etc. |
Preciso guardar um valor que não afeta a UI? | Dá, mas vai re-renderizar à toa. | SIM! Perfeito para IDs de timers, instâncias, contadores “invisíveis”. |
Um exemplo usando os dois
import React, { useState, useRef, useEffect } from "react";
function Stopwatch() {
const [seconds, setSeconds] = useState(0);
const intervalRef = useRef(null);
const startTimer = () => {
if (intervalRef.current) return; // Se já tem ID, tá rodando
intervalRef.current = setInterval(() => {
setSeconds((s) => s + 1); // Atualiza o estado, que atualiza a tela
}, 1000);
};
const pauseTimer = () => {
clearInterval(intervalRef.current);
intervalRef.current = null; // Limpa o ID pra indicar que não está rodando
};
// Importante: limpar o intervalo se o componente sumir da tela. Evita memory leaks.
useEffect(() => {
// Esta função de retorno é a 'cleanup function' do useEffect
return () => clearInterval(intervalRef.current);
}, []);
return (
<div>
<p>Time: {seconds}s</p>
<button onClick={startTimer}>Start</button>
<button onClick={pauseTimer}>Pause</button>
</div>
);
}
Sem o useRef
pro ID, se a gente colocasse ele num estado, cada setInterval
pode causar re-renderizações desnecessárias só pra guardar um número que não aparece.
Minha conclusão
No fim das contas, pra mim ficou assim:
-
useState
: É para UI dinâmica. Quer ver a coisa mudar na tela? Tenta usar ele. -
useRef
: É pra usar/modificar DOM e pra guardar valores “por baixo dos panos” sem fazer a tela piscar.