Section courante

A propos

Section administrative du site

useCallback

Utilise un appel en arrière-plan
Railo

Syntaxe

const cachedFn = useCallback(fn, dependencies)

Description

useCallback est un crochet React permettant d'entreposer en cache la définition d'une fonction entre deux rendus.

Remarques

Référence

useCallback(fn, dependencies)

Appelez useCallback au niveau supérieur de votre composant pour mettre en cache la définition d'une fonction entre les différents rendus :

  1. import { useCallback } from 'react';
  2.  
  3. export default function ProductPage({ productId, referrer, theme }) {
  4.   const handleSubmit = useCallback((orderDetails) => {
  5.     post('/product/' + productId + '/buy', {
  6.       referrer,
  7.       orderDetails,
  8.     });
  9.   }, [productId, referrer]);

Voir d'autres exemples ci-dessous.

Paramètres

Nom Description
fn Il s'agit de la fonction dont vous souhaitez entreposer la valeur en cache. Cette fonction peut prendre n'importe quel paramètre et retourner n'importe quelle valeur. React vous renverra (mais ne l'appellera pas) cette fonction lors du premier rendu. Lors des rendus suivants, React vous renverra la même fonction si les dépendances n'ont pas changé depuis le dernier rendu. Sinon, il vous renverra la fonction que vous avez fournie lors du rendu actuel et la stockera en mémoire pour une réutilisation ultérieure. React n'appellera pas votre fonction. Elle vous est simplement fournie afin que vous puissiez décider quand et si vous souhaitez l'appeler.
dependencies Cette liste répertorie toutes les valeurs réactives utilisées dans le code de la fonction. Les valeurs réactives comprennent les propriétés, l'état et toutes les variables et fonctions déclarées directement dans le corps de la composante. Si votre outil de vérification de code est configuré pour React, il vérifiera que chaque valeur réactive est correctement déclarée comme dépendance. La liste des dépendances doit contenir un nombre fixe d'éléments et être écrite de manière concise, comme [dep1, dep2, dep3]. React comparera chaque dépendance à sa valeur précédente à l'aide de l'algorithme de comparaison Object.is.

Valeur de retour

Lors du premier rendu, useCallback renvoie la fonction `fn` que vous avez passée en paramètre.

Lors des rendus suivants, il renverra soit la fonction `fn` précédemment entreposée (si les dépendances n'ont pas changé), soit la fonction `fn` que vous avez passée lors du rendu actuel.

Remarques

Utilisation

Optimisation des performances de rendu

Lors de l'optimisation des performances de rendu, il peut être nécessaire de mettre en cache les fonctions que vous transmettez aux composantes enfants. Voyons d'abord la syntaxe pour ce faire, puis les cas d'utilisation.

Pour mettre en cache une fonction entre les différents rendus de votre composant, encapsulez sa définition dans le crochet useCallback :

  1. import { useCallback } from 'react';
  2.  
  3. function ProductPage({ productId, referrer, theme }) {
  4.   const handleSubmit = useCallback((orderDetails) => {
  5.     post('/product/' + productId + '/buy', {
  6.       referrer,
  7.       orderDetails,
  8.     });
  9.   }, [productId, referrer]);
  10.   // ...

Vous devez passer deux éléments à la fonction useCallback :

Lors du premier rendu, la fonction retournée par useCallback sera la même que celle que vous avez passée en paramètre.

Lors des rendus suivants, React comparera les dépendances avec celles passées lors du rendu précédent. Si aucune dépendance n'a changé (comparaison effectuée avec Object.is), useCallback retournera la même fonction. Sinon, useCallback retournera la fonction passée lors de ce rendu.

Autrement dit, useCallback entrepose la fonction en mémoire entre les rendus successifs, jusqu'à ce que ses dépendances changent.

Prenons un exemple pour illustrer son utilité.

Supposons que vous transmettiez une fonction handleSubmit de la composante ProductPage au composante ShippingForm :

  1. function ProductPage({ productId, referrer, theme }) {
  2.   // ...
  3.   return (
  4.     <div className={theme}>
  5.       <ShippingForm onSubmit={handleSubmit} />
  6.     </div>
  7.   );

Vous avez remarqué que le changement de thème provoque un bref blocage de l'application. En revanche, si vous supprimez la composante <ShippingForm /> de votre code JSX, l'application fonctionne plus rapidement. Cela suggère qu'il serait judicieux d'optimiser le composante ShippingForm.

Par défaut, lorsque React re-rendu un composant, il re-rendu également tous ses enfants de manière récursive. Ainsi, lorsque ProductPage est re-rendu avec un nouveau thème, le composant ShippingForm est lui aussi re-rendu. Ce comportement est acceptable pour les composants dont le re-rendu ne nécessite pas de calculs complexes. Cependant, si vous constatez que le re-rendu de ShippingForm est lent, vous pouvez empêcher son re-rendu inutile en l'encapsulant dans la fonction memo() lorsque ses propriétés restent inchangées.

  1. import { memo } from 'react';
  2.  
  3. const ShippingForm = memo(function ShippingForm({ onSubmit }) {
  4.   // ...
  5. });

Grâce à ce changement, le composant ShippingForm omettra le re-rendu si toutes ses propriétés sont identiques à celles du rendu précédent. C'est à ce moment-là que le stockage en cache d'une fonction devient important ! Prenons l'exemple suivant : vous avez défini la fonction handleSubmit sans utiliser useCallback :

  1. function ProductPage({ productId, referrer, theme }) {
  2.   // À chaque changement de thème, cette fonction sera différente...
  3.   function handleSubmit(orderDetails) {
  4.     post('/product/' + productId + '/buy', {
  5.       referrer,
  6.       orderDetails,
  7.     });
  8.   }
  9.   
  10.   return (
  11.     <div className={theme}>
  12.       {/* ... Ainsi, les propriétés de ShippingForm seront toujours différentes, et la composante sera donc toujours redessiné. */}
  13.       <ShippingForm onSubmit={handleSubmit} />
  14.     </div>
  15.   );
  16. }

En JavaScript, une fonction définie avec la syntaxe () {} ou () => {} crée toujours une fonction différente, de la même manière qu'un objet créé avec la notation {} est toujours un nouvel objet. Normalement, cela ne pose pas de problème, mais cela signifie que les propriétés de la composante ShippingForm ne seront jamais identiques, ce qui rend l'optimisation par mémoire cache (memoization) inopérante. C'est là que la fonction useCallback s'avère utile :

  1. function ProductPage({ productId, referrer, theme }) {
  2.   // Indiquez à React de mettre en cache votre fonction entre les différents rendus...
  3.   const handleSubmit = useCallback((orderDetails) => {
  4.     post('/product/' + productId + '/buy', {
  5.       referrer,
  6.       orderDetails,
  7.     });
  8.   }, [productId, referrer]); // ...donc, tant que ces dépendances ne changent pas...
  9.  
  10.   return (
  11.     <div className={theme}>
  12.       {/* ...La composante ShippingForm recevra les mêmes propriétés et pourra ainsi éviter le re-rendu inutile. */}
  13.       <ShippingForm onSubmit={handleSubmit} />
  14.     </div>
  15.   );
  16. }

En enveloppant la fonction handleSubmit dans useCallback, vous vous assurez qu'elle reste la même lors des re-rendus (jusqu'à ce que les dépendances changent). Il n'est pas nécessaire d'utiliser useCallback pour toute fonction ; son utilisation doit être justifiée. Dans cet exemple, l'intérêt est de la passer à une composante enveloppé dans memo, ce qui permet d'éviter un re-rendu inutile. D'autres cas d'utilisation de useCallback sont décrits plus loin sur cette page.

Note

N'utilisez useCallback que pour optimiser les performances. Si votre code ne fonctionne pas sans, identifiez et corrigez d'abord le problème. Vous pourrez ensuite réintroduire useCallback.



Dernière mise à jour : Mercredi, le 10 septembre 2025