Aller au contenu

Les Hooks React avancés que vous devriez connaître

Explorez les hooks React avancés comme useCallback, useMemo et useRef pour optimiser vos composants et améliorer les performances.

Au-delà des hooks basiques useState et useEffect, React propose des hooks avancés qui permettent d'optimiser les performances et de gérer des cas d'usage complexes.

useCallback - Mémoriser les fonctions

useCallback permet de mémoriser une fonction pour éviter sa recréation à chaque rendu. C'est particulièrement utile lorsque vous passez des callbacks à des composants enfants optimisés.

Le problème

Sans useCallback, chaque rendu crée une nouvelle référence de fonction :

function Parent() {
  const [count, setCount] = useState(0);

  // ❌ Nouvelle fonction à chaque rendu
  const handleClick = () => {
    console.log('Clicked!');
  };

  return <Child onClick={handleClick} />;
}

La solution

function Parent() {
  const [count, setCount] = useState(0);

  // ✅ Même référence entre les rendus
  const handleClick = useCallback(() => {
    console.log('Clicked!');
  }, []);

  return <Child onClick={handleClick} />;
}

useMemo - Mémoriser les calculs coûteux

useMemo permet de mémoriser le résultat d'un calcul coûteux :

function ProductList({ products, filter }: Props) {
  // Calcul mémorisé - ne s'exécute que si products ou filter change
  const filteredProducts = useMemo(() => {
    return products.filter((product) =>
      product.name.toLowerCase().includes(filter.toLowerCase())
    );
  }, [products, filter]);

  return (
    <ul>
      {filteredProducts.map((product) => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
}

Attention : N'utilisez pas useMemo partout ! Réservez-le aux calculs vraiment coûteux.

useRef - Persister des valeurs

useRef a deux usages principaux :

  1. Accéder aux éléments DOM
  2. Persister des valeurs entre les rendus sans déclencher de re-rendu

Accès au DOM

function TextInput() {
  const inputRef = useRef<HTMLInputElement>(null);

  const focusInput = () => {
    inputRef.current?.focus();
  };

  return (
    <>
      <input ref={inputRef} type="text" />
      <button onClick={focusInput}>Focus</button>
    </>
  );
}

Valeur persistante

function Timer() {
  const [count, setCount] = useState(0);
  const intervalRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    intervalRef.current = setInterval(() => {
      setCount((c) => c + 1);
    }, 1000);

    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, []);

  return <p>Count: {count}</p>;
}

useReducer - État complexe

Pour les états complexes avec plusieurs sous-valeurs, useReducer est souvent plus adapté que useState :

type State = {
  loading: boolean;
  error: string | null;
  data: User | null;
};

type Action =
  | { type: 'FETCH_START' }
  | { type: 'FETCH_SUCCESS'; payload: User }
  | { type: 'FETCH_ERROR'; payload: string };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'FETCH_START':
      return { ...state, loading: true, error: null };
    case 'FETCH_SUCCESS':
      return { loading: false, error: null, data: action.payload };
    case 'FETCH_ERROR':
      return { loading: false, error: action.payload, data: null };
    default:
      return state;
  }
}

function UserProfile({ userId }: { userId: string }) {
  const [state, dispatch] = useReducer(reducer, {
    loading: false,
    error: null,
    data: null,
  });

  // Utilisation avec dispatch...
}

Quand utiliser quoi ?

Voici un récapitulatif :

HookUtilisation
useCallbackFonctions passées en props
useMemoCalculs coûteux
useRefDOM ou valeurs persistantes
useReducerÉtats complexes

Bonnes pratiques

Pour résumer les bonnes pratiques :

  • Mesurez avant d'optimiser - Utilisez React DevTools Profiler
  • Évitez l'optimisation prématurée - La lisibilité prime
  • Dépendances correctes - Incluez toutes les valeurs utilisées
  • Custom hooks - Extrayez la logique réutilisable

Conclusion

Les hooks avancés de React sont des outils puissants pour optimiser vos applications. Utilisez-les judicieusement en vous concentrant sur les cas où ils apportent une réelle valeur ajoutée.

Commentaires

Les commentaires sont gérés via GitHub Discussions. En cliquant sur "Accepter", vous autorisez le chargement de contenu externe depuis GitHub.

Vos données seront traitées selon la politique de confidentialité de GitHub.