Chapitre 19 — Bonnes pratiques React
React est déjà performant, mais dans certaines situations, votre application peut re-render (recalculer / ré-afficher) trop souvent, ce qui peut ralentir l’UI. Dans ce chapitre, vous allez comprendre quand et comment utiliser : useMemo , useCallback et React.memo .
Plan du chapitre
1) Rappel : pourquoi ça re-render ?
Un composant React se re-render quand :
- son state change
- ses props changent
- son parent se re-render (et lui re-render aussi)
Re-render ne veut pas dire “mauvais”. C’est normal. On optimise seulement quand on a un vrai problème.
2) React.memo : mémoriser un composant
React.memo dit à React : “si les props n’ont pas changé, ne re-render pas ce composant”.
C’est utile quand un composant enfant coûte cher à re-render, et que le parent re-render souvent.
import React from "react";
function BigChild({ title }) {
console.log("BigChild re-render");
return <h3>{title}</h3>;
}
export default React.memo(BigChild);
Si title reste identique, BigChild ne se re-render pas même si le parent re-render.
3) useCallback : mémoriser une fonction
Problème fréquent : à chaque re-render, une fonction est “recréée”. Donc, si vous la passez en prop à un enfant, React considère que la prop a changé (nouvelle référence).
Exemple : sans useCallback
function Parent() {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log("click");
};
return <Child onClick={handleClick} />;
}
À chaque re-render du Parent, handleClick est une nouvelle fonction.
Si Child est memoïsé, il re-render quand même car la prop change.
Solution : useCallback
import { useCallback, useState } from "react";
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("click");
}, []);
return <Child onClick={handleClick} />;
}
useCallback(fn, deps) renvoie la même fonction tant que les dépendances ne changent pas.
4) useMemo : mémoriser un calcul
Si vous avez un calcul coûteux (ex : filtrer une grande liste, calcul mathématique lourd), vous ne voulez pas le recalculer à chaque re-render si les données n’ont pas changé.
Sans useMemo
const filtered = items.filter((x) => x.includes(search));
Avec useMemo
import { useMemo } from "react";
const filtered = useMemo(() => {
return items.filter((x) => x.includes(search));
}, [items, search]);
Le calcul est refait uniquement si items ou search change.
5) Quand optimiser (et quand ne pas le faire)
À retenir : optimiser trop tôt complique le code. Optimisez quand vous avez :
- des listes très grandes
- des composants lourds
- des re-renders visibles (lenteur)
- un vrai besoin de stabilité des props (memo + callback)
Règle simple : si vous n’avez pas de problème de perf, n’optimisez pas.
6) Erreurs fréquentes
J’utilise useMemo partout
Mauvaise idée : cela rend le code plus dur à lire. Utilisez-le seulement sur des calculs coûteux.
J’ai oublié les dépendances
useMemo et useCallback doivent inclure les valeurs utilisées dans la fonction.
Sinon vous aurez des valeurs “pas à jour”.
React.memo ne marche “pas”
Souvent, c’est parce que vous passez des objets/fonctions recréés à chaque rendu.
Dans ce cas, combinez avec useMemo ou useCallback.
7) Résumé (à retenir)
React.memoévite de re-render un composant si ses props n’ont pas changé.useCallbackstabilise une fonction passée en prop.useMemostabilise un résultat de calcul.- On optimise seulement quand c’est utile.
8) Exercice pratique
Créez une liste de 1000 éléments (ex : des noms) et un champ de recherche.
- Filtrez la liste selon la recherche.
- Utilisez
useMemopour éviter de recalculer le filtre inutilement. - Créez un composant enfant
Listmemoïsé avecReact.memo. - Passez une fonction “onSelect” au composant List, et stabilisez-la avec
useCallback.
Prochaine étape : Chapitre 20 — Patterns d’architecture : composants contrôlés, levée de state, composition, et bonnes pratiques de structure.