React

Maîtriser les React Hooks avancés : useCallback, useMemo, useRef

Découvrez comment maîtriser les hooks avancés de React pour optimiser vos applications.

26 Jan 2026 3 min de lecture 51 vues
51

Lectures

3

Minutes

0

Partages

Introduction

Dans le monde du développement web moderne, React a apporté une révolution sans précédent avec ses composants fonctionnels et ses hooks. Ces derniers sont conçus pour simplifier la gestion de l'état et des effets secondaires, tout en rendant le code plus lisible et plus maintenable. Parmi les hooks les plus puissants, mais souvent mal compris, on trouve useCallback, useMemo et useRef. Cet article se propose de vous guider à travers ces hooks avancés, en vous montrant comment et quand les utiliser pour optimiser les performances de vos applications React. Alors que React gère automatiquement les mises à jour de votre interface utilisateur, il est crucial de comprendre que chaque mise à jour peut entraîner un re-rendu des composants enfants. Cela peut devenir coûteux en termes de performances, surtout dans les applications complexes. Les hooks avancés mentionnés ci-dessus vous permettent de contrôler ce comportement et d'éviter des recalculs inutiles. Ceci est essentiel pour maintenir une expérience utilisateur fluide et réactive.

Comprendre les Hooks de Performance

Avant de plonger dans les détails des hooks avancés, il est important de comprendre pourquoi ils existent et comment ils fonctionnent. En React, chaque fois qu’un composant se met à jour, il peut entraîner le re-rendu de ses enfants. Cela signifie que si vous avez des fonctions ou des calculs coûteux qui sont exécutés à chaque rendu, cela peut ralentir votre application de manière significative.

useCallback

Le hook useCallback est utilisé pour mémoriser une fonction afin qu’elle ne soit pas recréée à chaque rendu. Cela est particulièrement utile lorsque vous passez des fonctions en props à des composants enfants qui peuvent se re-rendre inutilement si la référence de la fonction change.

import React, { useState, useCallback } from 'react';

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

  const increment = useCallback(() => {
    setCount((prevCount) => prevCount + 1);
  }, []); // La dépendance vide signifie que la fonction est créée une seule fois

  return (
    

Count: {count}

); }

useMemo

Le hook useMemo sert à mémoriser le résultat d’un calcul coûteux. Il ne recalcule la valeur que lorsque l'une des dépendances change, ce qui permet d’optimiser les performances en évitant des calculs inutiles.

import React, { useState, useMemo } from 'react';

function ExpensiveComputation({ num }) {
  const computeFactorial = (n) => {
    console.log('Calculating factorial...');
    return n <= 0 ? 1 : n * computeFactorial(n - 1);
  };

  const factorial = useMemo(() => computeFactorial(num), [num]);

  return 
Factorial of {num} is {factorial}
; }

useRef

Le hook useRef est principalement utilisé pour accéder directement à un élément DOM. Cependant, il peut également être utilisé comme un conteneur pour stocker une valeur mutable qui ne nécessite pas de re-rendu lors de sa modification.

import React, { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <>
      
      
    
  );
}

Bonnes pratiques pour l'utilisation des Hooks avancés

L'utilisation de ces hooks doit être bien pensée pour éviter de complexifier inutilement votre code. Voici quelques bonnes pratiques :

Utiliser useCallback judicieusement

N'utilisez useCallback que lorsque vous avez des composants enfants qui reposent sur des fonctions passées en props. Si vous n'avez pas de problèmes de performance, il est souvent préférable de ne pas l'utiliser.

Limiter les dépendances de useMemo

Lors de l'utilisation de useMemo, assurez-vous que les dépendances sont clairement définies et limitées aux variables qui influencent réellement le calcul. Cela évite des recalculs inutiles et optimise les performances.

Eviter les pièges courants avec useRef

Bien que useRef puisse sembler simple, il est essentiel de comprendre qu'il ne provoque pas de re-rendu lorsque sa valeur change. Utilisez-le pour stocker des valeurs qui devraient persister entre les rendus sans déclencher de nouveaux rendus.

Pièges courants à éviter

Malgré leurs avantages, ces hooks peuvent introduire des complexités si mal utilisés. Voici quelques pièges courants à éviter :

Abus de useCallback et useMemo

L'utilisation excessive de useCallback et useMemo peut rendre votre code difficile à lire et à maintenir. Assurez-vous de n'utiliser ces hooks que lorsque cela est nécessaire pour résoudre un problème de performance identifié.

Ignorer les dépendances

Oublier d'ajouter toutes les dépendances nécessaires dans les tableaux de dépendances de useCallback ou useMemo peut conduire à des bugs difficiles à déboguer car la fonction ou la valeur mémorisée ne se met pas à jour correctement.

Usage incorrect de useRef

Utiliser useRef pour stocker l'état qui devrait être réactif est une erreur courante. Rappelez-vous que les modifications apportées à useRef ne déclenchent pas de re-rendus, ce qui peut conduire à des incohérences si mal utilisé.

Cas d'usage réels

Pour mieux comprendre l'application de ces hooks, examinons quelques scénarios réels où ils peuvent s'avérer extrêmement utiles.

Optimisation de composants list

Dans une liste de composants où chaque élément est un composant complexe, l'utilisation de useCallback pour les gestionnaires d'événements et de useMemo pour les calculs lourds peut considérablement améliorer les performances.

Gestion de formulaire complexe

Dans les formulaires complexes avec de nombreux champs, useRef peut être utilisé pour stocker des références à des éléments DOM ou à des valeurs de champ intermédiaires sans provoquer de re-rendu.

Comparaison des Hooks avancés

Pour mieux visualiser les différentes utilisations de ces hooks avancés, voici un tableau comparatif :
Hook Utilisation principale Quand l'utiliser
useCallback Mémoriser une fonction Lorsque vous passez des fonctions en props à des composants enfants
useMemo Mémoriser le résultat d'un calcul Pour des calculs lourds ou coûteux en performance
useRef Accéder à des éléments DOM ou stocker des valeurs persistantes Pour stocker des valeurs qui ne nécessitent pas de re-rendu

Conseil pro : Utilisez ces hooks avec parcimonie et uniquement lorsque vous en avez réellement besoin pour résoudre des problèmes de performance ou de gestion d'état complexe. Leur utilisation abusive peut compliquer inutilement votre code.

Conclusion

Maîtriser les hooks avancés de React tels que useCallback, useMemo et useRef est essentiel pour tout développeur cherchant à optimiser les performances de ses applications. Ces hooks offrent des solutions élégantes pour éviter les re-rendus inutiles et gérer l'état de manière efficace. Cependant, leur utilisation doit être bien réfléchie pour éviter de rendre le code plus compliqué qu'il ne doit l'être. En suivant les bonnes pratiques et en évitant les pièges courants, vous pouvez tirer pleinement parti de ces outils puissants pour créer des applications React performantes et maintenables.

Patterns avancés avec les hooks React

Au-delà de useCallback et useMemo, d'autres hooks avancés permettent de construire des composants robustes et performants. Voici les patterns les plus utilisés en production.

useReducer : gérer un état complexe

// Préférer useReducer à useState quand l'état a plusieurs sous-valeurs liées
const initialState = { loading: false, data: null, error: null };

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

function useArticles() {
  const [state, dispatch] = useReducer(fetchReducer, initialState);

  const fetchArticles = useCallback(async () => {
    dispatch({ type: 'FETCH_START' });
    try {
      const res = await fetch('/api/articles');
      const data = await res.json();
      dispatch({ type: 'FETCH_SUCCESS', payload: data });
    } catch (error) {
      dispatch({ type: 'FETCH_ERROR', error: error.message });
    }
  }, []);

  return { ...state, fetchArticles };
}

useRef : valeurs mutables sans re-render

function Timer() {
  const [seconds, setSeconds] = useState(0);
  const intervalRef = useRef(null);  // Ne déclenche PAS de re-render

  const start = useCallback(() => {
    intervalRef.current = setInterval(() => {
      setSeconds(s => s + 1);
    }, 1000);
  }, []);

  const stop = useCallback(() => {
    clearInterval(intervalRef.current);
  }, []);

  // Cleanup au démontage
  useEffect(() => () => clearInterval(intervalRef.current), []);

  return 
{seconds}s
; }

Conseil pro : Utilisez React DevTools Profiler pour identifier les composants qui se re-rendent inutilement avant d'optimiser avec useCallback/useMemo. Optimiser prématurément sans mesurer est contre-productif et complexifie le code inutilement.

Quand utiliser chaque hook d'optimisation

HookMémoriseUtiliser quandÉviter si
useMemoValeur calculéeCalcul coûteux ou tableau/objet stableCalcul simple (< 1ms)
useCallbackRéférence de fonctionProp vers composant mémoïséComposant enfant non mémoïsé
React.memoComposant entierRe-renders fréquents avec mêmes propsProps changent souvent
useReducerÉtat avec multiples sous-valeurs liéesÉtat simple (booléen, string)

Tags

React Hooks Performance

Partagez cet article

Twitter Facebook LinkedIn
JY
Jordane YENO

Developpeur Full Stack passionne par le web et les nouvelles technologies

En savoir plus

Articles similaires