useRef est un hook qui crée une référence mutable qui persiste entre les rendus, sans déclencher de re-rendu quand elle change.
const myRef = useRef(valeurInitiale);
// myRef = { current: valeurInitiale }
// On accède/modifie via : myRef.current
Comme document.getElementById() mais à la manière React :
function FocusInput() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus(); // Accède directement au DOM
inputRef.current.style.borderColor = '#61dafb';
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus l'input</button>
</>
);
}
Contrairement à useState, modifier un ref ne provoque pas de re-rendu :
function Compteur() {
const [count, setCount] = useState(0);
const renderCount = useRef(0);
// À chaque rendu, on incrémente le ref
renderCount.current += 1;
return (
<div>
<p>Count: {count}</p>
<p>Rendus: {renderCount.current}</p>
<button onClick={() => setCount(c => c + 1)}>+1</button>
</div>
);
}
| useState | useRef | |
|---|---|---|
| Déclenche un re-rendu ? | ✅ Oui | ❌ Non |
| Persiste entre les rendus ? | ✅ Oui | ✅ Oui |
| Usage principal | Données affichées | Valeurs « cachées », refs DOM |
| Accès | valeur | ref.current |
function Timer() {
const [secondes, setSecondes] = useState(0);
const timerRef = useRef(null);
const start = () => {
if (timerRef.current) return; // Déjà lancé
timerRef.current = setInterval(() => {
setSecondes(s => s + 1);
}, 1000);
};
const stop = () => {
clearInterval(timerRef.current);
timerRef.current = null;
};
return (
<div>
<p>{secondes}s</p>
<button onClick={start}>Start</button>
<button onClick={stop}>Stop</button>
</div>
);
}
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
useState si la valeur doit être affichée. Utilise useRef si c'est une valeur interne qui ne doit pas déclencher de re-rendu.
▼ useRef en action
useRef(init) retourne { current: init }.<input ref={myRef} /> → myRef.current.focus().useState. Sinon → useRef.