useLayoutEffect |
Utilise une couche d'effet |
|---|---|
| React | |
Piège : useLayoutEffect peut nuire aux performances. Privilégiez useEffect lorsque cela est possible.
| useLayoutEffect(setup, dependencies?) |
useLayoutEffect est une version de useEffect qui se déclenche avant que le navigateur ne redessine l'écran.
Référence
| useLayoutEffect(setup, dependencies?) |
Appelez useLayoutEffect pour effectuer les mesures de mise en page avant que le navigateur ne repeigne l'écran :
- import { useState, useRef, useLayoutEffect } from 'react';
-
- function Tooltip() {
- const ref = useRef(null);
- const [tooltipHeight, setTooltipHeight] = useState(0);
-
- useLayoutEffect(() => {
- const { height } = ref.current.getBoundingClientRect();
- setTooltipHeight(height);
- }, []);
- // ...
Paramètres
| Nom | Description |
|---|---|
| setup | La fonction contenant la logique de votre effet. Votre fonction de configuration peut également renvoyer une fonction de nettoyage (optionnelle). Avant l'ajout de votre composant au DOM, React exécutera votre fonction de configuration. Après chaque nouveau rendu avec des dépendances modifiées, React exécutera d'abord la fonction de nettoyage (si vous l'avez fournie) avec les anciennes valeurs, puis exécutera votre fonction de configuration avec les nouvelles valeurs. Avant la suppression de votre composant du DOM, React exécutera votre fonction de nettoyage. |
| dependencies | optionnelles : La liste de toutes les valeurs réactives référencées dans le code de configuration. Les valeurs réactives incluent les propriétés, l'état et toutes les variables et fonctions déclarées directement dans le corps de votre composant. Si votre linter est configuré pour React, il vérifiera que chaque valeur réactive est correctement spécifiée comme dépendance. La liste des dépendances doit comporter un nombre constant d'éléments et être écrite en ligne, comme [dep1, dep2, dep3]. React comparera chaque dépendance à sa valeur précédente grâce à la comparaison Object.is. Si vous omettez cet argument, votre effet sera réexécuté après chaque rendu de la composante. |
Renvoie
useLayoutEffect renvoie undefined.
Mises en garde
- useLayoutEffect est un crochet ; vous ne pouvez donc l'appeler qu'au niveau supérieur de votre composant ou de vos propres crochets. Vous ne pouvez pas l'appeler à l'intérieur de boucles ou de conditions. Si nécessaire, extrayez un composant et déplacez-y l'effet.
- En mode strict, React exécute un cycle supplémentaire de configuration et de nettoyage, réservé au développement, avant la première configuration réelle. Il s'agit d'un test de résistance qui garantit que votre logique de nettoyage reflète celle de la configuration et qu'elle arrête ou annule l'exécution de la configuration. Si cela pose problème, implémentez la fonction de nettoyage.
- Si certaines de vos dépendances sont des objets ou des fonctions définis dans le composant, elles risquent de provoquer une réexécution de l'effet plus souvent que nécessaire. Pour résoudre ce problème, supprimez les dépendances d'objets et de fonctions inutiles. Vous pouvez également extraire les mises à jour d'état et la logique non réactive en dehors de votre effet.
- Les effets ne s'exécutent que sur le client. Ils ne s'exécutent pas pendant le rendu serveur.
- Le code de useLayoutEffect et toutes les mises à jour d'état planifiées depuis celui-ci empêchent le navigateur de redessiner l'écran. Une utilisation excessive ralentit votre application. Privilégiez useEffect autant que possible.
- Si vous déclenchez une mise à jour d'état dans useLayoutEffect, React exécutera immédiatement tous les effets restants, y compris useEffect.
Utilisation
Mesurer la disposition avant que le navigateur ne redessine l'écran
La plupart des composants n'ont pas besoin de connaître leur position et leur taille à l'écran pour déterminer le rendu. Ils renvoient simplement du code JSX. Le navigateur calcule ensuite leur disposition (position et taille) et redessine l'écran.
Parfois, cela ne suffit pas. Imaginez une info-bulle qui apparaît à côté d'un élément au survol. Si l'espace est suffisant, l'info-bulle devrait apparaître au-dessus de l'élément, mais si elle ne rentre pas, elle devrait apparaître en dessous. Pour que l'info-bulle soit affichée à la bonne position finale, vous devez connaître sa hauteur (c'est-à-dire si elle tient en haut).
Pour ce faire, vous devez effectuer le rendu en deux étapes :
- Afficher l'info-bulle n'importe où (même avec une position incorrecte).
- Mesurer sa hauteur et décider où placer l'info-bulle.
Afficher à nouveau l'info-bulle au bon endroit.
Tout cela doit être effectué avant que le navigateur ne redessine l'écran. L'utilisateur ne doit pas voir l'info-bulle bouger. Appelez useLayoutEffect pour effectuer les mesures de mise en page avant que le navigateur ne repeigne l'écran :
- function Tooltip() {
- const ref = useRef(null);
- const [tooltipHeight, setTooltipHeight] = useState(0); // Vous ne connaissez pas encore la vraie taille
-
- useLayoutEffect(() => {
- const { height } = ref.current.getBoundingClientRect();
- setTooltipHeight(height); // Re-rendez maintenant que vous connaissez la hauteur réelle
- }, []);
-
- // ...utilisez tooltipHeight dans la logique de rendu ci-dessous...
- }
Voici comment cela fonctionne étape par étape :
- L'info-bulle s'affiche avec la valeur initiale tooltipHeight = 0 (l'info-bulle peut donc être mal positionnée).
- React la place dans le DOM et exécute le code dans useLayoutEffect.
- Votre useLayoutEffect mesure la hauteur du contenu de l'info-bulle et déclenche un nouveau rendu immédiat.
- L'info-bulle s'affiche à nouveau avec la valeur réelle tooltipHeight (l'info-bulle est donc correctement positionnée).
- React la met à jour dans le DOM, et le navigateur affiche enfin l'info-bulle.