12 — useRef

🔍 C'est quoi useRef ?

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

📐 2 usages principaux

1. Accéder à un élément DOM

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>
        </>
    );
}

2. Stocker une valeur mutable (sans re-rendu)

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>
    );
}

⚡ useRef vs useState

useStateuseRef
Déclenche un re-rendu ?✅ Oui❌ Non
Persiste entre les rendus ?✅ Oui✅ Oui
Usage principalDonnées affichéesValeurs « cachées », refs DOM
Accèsvaleurref.current

📦 Cas d'usage courants

Stocker un timer ID

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>
    );
}

Conserver la valeur précédente

function usePrevious(value) {
    const ref = useRef();
    useEffect(() => {
        ref.current = value;
    }, [value]);
    return ref.current;
}
💡 Règle : Utilise 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.

🚀 Démo interactive

▼ useRef en action

📝 Résumé

← 11 — Lifting State 13 — useContext →