Les Hooks React avancés : useCallback, useMemo, useContext, useRef, useImperativeHandle et useLayoutEffect

useCallback et useMemo

Ces deux Hooks partagent le même objectif : éviter des recalculs ou des re-créations de fonctions inutiles entre les rendus. La différence réside dans leur retour : useMemo mémorise une valeur, tandis que useCallback mémorise une fonction.


// Signature de useMemo
const valeurMemoisee = useMemo(() => calculLourd(a, b), [a, b]);

// Signature de useCallback
const fonctionMemoisee = useCallback((x) => faireQuelqueChose(x), [dependance]);

Dans React, si une propriété passée à un enfant change de référence (même si sa valeur reste identique), l'enfant se re-rend. Ces Hooks résolvent ce problème en stabilisant les références. Ils réduisent également le nombre de recalculs inutiles.

useRef

useRef remplace createRef dans les composants fonction. Il permet de stocker une valeur mutable qui persiste entre les rendus sans déclencher de nouveau rendu.


import { useRef } from 'react';

function MonComposant() {
  const inputRef = useRef(null);
  const handleClick = () => inputRef.current.focus();
  return <><input ref={inputRef} /><button onClick={handleClick}>Focus</button></>;
}

useContext

useContext simplifie l'utilisation du Context.Provider des classes. Il accepte un objet contexte (créé par React.createContext) et retorune sa valeur courante.


const ThemeContext = React.createContext('clair');

function Bouton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Cliquez</button>;
}

useImperativeHandle

useImperativeHandle personnalise la valeur exposée au parent via ref. Il s'utilise toujours avec forwardRef. L'objectif est de limiter l'accès direct au DOM et de n'exposer que certaines méthodes.


function ChampSaisie({ ...props }, refExterne) {
  const elementInterne = useRef(null);

  useImperativeHandle(refExterne, () => ({
    focus: () => elementInterne.current.focus(),
    effacer: () => { elementInterne.current.value = ''; }
  }));

  return <input ref={elementInterne} />;
}
const ChampAvecRef = forwardRef(ChampSaisie);

// Utilisation dans le parent
function Parent() {
  const refChamp = useRef(null);
  return <><ChampAvecRef ref={refChamp} /><button onClick={() => refChamp.current.focus()}>Focus</button></>;
}

Remarque : useImperativeHandle était initialement nommé useImperativeMethods dans les premières versions. La version actuelle utilise useImperativeHandle. useMutationEffect a été abandonné ; il ne fait plus partie de l'API stable.

useLayoutEffect

La signature est identique à useEffect :

useLayoutEffect(() => {
  // code synchrone après les mutations DOM
  return () => { /* nettoyage */ };
}, [dependances]);

Contrairement à useEffect, useLayoutEffect s'exécute de manière synhcrone immédiatement après que React a appliqué les mutations DOM, mais avant que le navigateur n'ait effectué le rendu visuel. Il est utile pour lire ou modifier la mise en page (par exemple mesurer la hauteur d'un élément) sans provoquer de flash blanc. On peut le comparer au nextTick de Vue.js.

Étiquettes: React Hooks JavaScript useCallback useMemo

Publié le 5 juillet à 03h34