Les deux mettent en cache quelque chose au-delà des renders pour qu'il ne soit pas recalculé/recréé à chaque fois :
Les deux mettent en cache quelque chose au-delà des renders pour qu'il ne soit pas recalculé/recréé à chaque fois :
useMemo met en cache une valeur calculée.useCallback met en cache l'identité d'une fonction (c'est useMemo(() => fn, deps)).Ils existent pour éviter (a) de répéter un travail coûteux et (b) de briser l'égalité référentielle sur laquelle les enfants memoized dépendent.
function Table({ rows, onSelect }) {
// (a) expensive computation — recompute only when `rows` changes
const sorted = useMemo(() => rows.slice().sort(byName), [rows]);
// (b) stable function identity — so a React.memo child doesn't re-render,
// and effects depending on it don't re-fire
const handleSelect = useCallback(id => onSelect(id), [onSelect]);
return <Grid rows={sorted} onSelect={handleSelect} />;
}
Sans useCallback, handleSelect est une toute nouvelle fonction à chaque render. Un React.memo(Grid) verrait une prop "nouvelle" et se re-rendrait de toute façon, défaisant la memoization. La même chose pour un objet passé à un enfant memoized ou utilisé dans un tableau de dépendances useEffect.
const x = useMemo(() => a + b, [a, b]); // ❌ pointless — adding is cheaper than memoizing
useMemo/useCallback prématuré partout ajoute du bruit et peut même être plus lent. (Le compilateur de React 19 peut auto-memoizer, réduisant le besoin.)