useTransition
Référence
useTransition()
Appelez useTransition
au niveau racine de votre composant pour marquer certaines mises à jour d’état comme étant des Transitions.
.
Paramètres
useTransition
ne prend aucun argument.
Valeur renvoyée
useTransition
renvoie un tableau avec exactement deux éléments :
- Le drapeau
isPending
qui vous indique si la Transition est en cours. - La qui vous permet de marquer une mise à jour d’état comme Transition.
La fonction startTransition
La fonction startTransition
renvoyée par useTransition
vous permet de marquer une mise à jour d’état comme étant une Transition.
Paramètres
scope
: une fonction qui met à jour l’état en appelant au moins une . React appelle immédiatementscope
sans argument et marque toutes les mises à jour d’état demandées durant l’exécution synchrone descope
comme des Transitions. Elles seront et .
Valeur renvoyée
startTransition
ne renvoie rien.
Limitations et points à noter
useTransition
est un Hook, il ne peut donc être appelé qu’au sein de composants ou de Hooks personnalisés. Si vous avez besoin de démarrer une Transition à un autre endroit (par exemple, depuis une bibliothèque de gestion de données), utilisez plutôt la fonction autonome .Vous pouvez enrober une mise à jour dans une Transition uniquement si vous avez accès à la fonction
set
de l’état en question. Si vous souhaitez démarrer une Transition en réaction à une prop ou à la valeur renvoyée par un Hook personnalisé, utilisez plutôt .La fonction que vous passez à
startTransition
doit être synchrone. React exécute cette fonction immédiatement, et marque toutes les mises à jour demandées lors de son exécution comme des Transitions. Si vous essayez de faire des mises à jour d’état plus tard (par exemple avec un timer), elles ne seront pas marquées comme des Transitions.La fonction
startTransition
a une identité stable, elle ne figure donc généralement pas dans les dépendances des Effets, mais l’inclure n’entraînera pas un déclenchement d’Effet superflu. Si le linter vous permet de l’omettre sans erreurs, c’est que cette omission est sans danger.Une mise à jour d’état marquée comme une Transition pourra être interrompue par d’autres mises à jour d’état. Par exemple, si vous mettez à jour un composant de graphe au sein d’une Transition, mais commencez alors une saisie dans un champ texte tandis que le graphe est en train de refaire son rendu, React redémarrera le rendu du composant graphe après avoir traité la mise à jour d’état du champ.
Les mises à jour en Transition ne peuvent pas être utilisées pour contrôler des champs textuels.
Si plusieurs Transitions sont en cours, React les regroupe pour le moment. Cette limitation sera sans doute levée dans une future version.
Utilisation
Marquer une mise à jour d’état comme étant une Transition non bloquante
Appelez useTransition
au niveau racine de votre composant pour marquer des mises à jour d’état comme étant des Transitions non bloquantes.
useTransition
renvoie un tableau avec exactement deux éléments :
- Le drapeau
isPending
qui vous indique si la Transition est en cours. - La fonction
startTransition
qui vous permet de marquer une mise à jour d’état comme Transition.
Vous pouvez marquer une mise à jour d’état comme étant une Transition de la façon suivante :
Les Transitions vous permettent de conserver la réactivité des mises à jour d’interface utilisateur, même sur des appareils lents.
Avec une Transition, votre UI reste réactive pendant le rendu. Par exemple, si l’utilisateur clique sur un onglet mais ensuite change d’avis et va sur un autre onglet, il peut le faire sans devoir d’abord attendre que le premier onglet ait fini son rendu.
Mettre à jour le composant parent dans une Transition
Vous pouvez tout aussi bien mettre à jour l’état du composant parent depuis un appel à useTransition
. Par exemple, le composant TabButton
enrobe la logique de son onClick
avec une Transition :
Puisque le composant parent met à jour son état au sein du gestionnaire d’événement onClick
, cette mise à jour d’état sera marquée comme étant une Transition. C’est pourquoi, comme dans l’exemple précédent, vous pouvez cliquer sur « Articles » puis immédiatement sur « Contact ». Le changement d’onglet est marqué comme étant une Transition : il ne bloque donc pas les interactions utilisateur.
Afficher une indication visuelle pendant la Transition
Vous pouvez utiliser la valeur booléenne isPending
renvoyée par useTransition
pour indiquer à l’utilisateur qu’une Transition est en cours. Par exemple, le bouton d’onglet peut avoir un état visuel spécial « en cours » :
Remarquez que le clic sur « Articles » semble désormais plus réactif parce que le bouton d’onglet lui-même se met à jour immédiatement :
Empêcher les indicateurs de chargement indésirables
Dans cet exemple, le composant PostsTab
charge des données en utilisant une source de données . Lorsque vous cliquez sur l’onglet « Articles », le composant PostsTab
suspend, entraînant l’affichage du plus proche contenu de secours :
Masquer le conteneur d’onglets dans son intégralité pour afficher un indicateur de chargement entraîne une expérience utilisateur désagréable. Si vous ajoutez useTransition
à TabButton
, vous pouvez plutôt manifester l’attente en cours dans le bouton d’onglet.
Remarquez que cliquer sur « Articles » ne remplace plus l’ensemble du conteneur d’onglets avec un spinner :
.
Construire un routeur compatible Suspense
Si vous construisez un framework React ou un routeur, nous vous recommandons de marquer toutes les navigations de pages comme étant des Transitions.
Nous recommandons ça pour deux raisons :
- , ce qui permet à l’utilisateur de cliquer pour aller ailleurs sans devoir attendre la fin du rendu de son premier choix.
- , ce qui vous évite de produire des « clignotements » désagréables lors de la navigation.
Voici un petit exemple de routeur très simplifié utilisant les Transitions pour ses navigations.
Afficher une erreur à l’utilisateur avec un périmètre d’erreur
Si une fonction passée à startTransition
lève une erreur, vous pouvez afficher l’erreur à votre utilisateur au moyen d’un . Pour utiliser un périmètre d’erreur, enrobez le composant qui appelle useTransition
avec ce périmètre. Lorsque la fonction passée à startTransition
lèvera une erreur, le contenu de secours du périmètre d’erreur sera affiché.
Dépannage
Mettre à jour un champ depuis une Transition ne fonctionne pas
Vous ne pouvez pas utiliser une Transition pour mettre à jour une variable d’état qui contrôle un champ :
C’est parce que les Transitions sont non bloquantes, alors que la mise à jour d’un champ en réaction à un événement de modification doit survenir de façon synchrone. Si vous souhaitez exécuter une Transition en réponse à une saisie, vous avez deux options :
- Vous pouvez déclarer deux variables d’état distinctes : une pour l’état du champ (qui sera toujours mise à jour de façon synchrone), et une que vous mettrez à jour au sein d’une Transition. Ça vous permet de contrôler le champ avec l’état synchrone, tout en passant la variable d’état en Transition (qui est susceptible de « retarder » par rapport à la saisie) au reste de votre logique de rendu.
- Sinon, vous pouvez n’avoir qu’une variable d’état et utiliser qui vous permettra d’être « en retard » sur la véritable valeur. Ça déclenchera automatiquement des rendus non bloquants pour « rattraper » la nouvelle valeur.
React ne traite pas ma mise à jour d’état comme étant une Transition
Lorsque vous enrobez une mise à jour d’état dans une Transition, assurez-vous qu’elle survient effectivement pendant l’appel à startTransition
:
La fonction que vous passez à startTransition
doit être synchrone.
Vous ne pouvez pas marquer une mise à jour comme étant une Transition avec ce genre de code :
Faites plutôt ceci :
Dans le même esprit, vous ne pouvez pas marquer une mise à jour comme étant une Transition avec du code ressemblant à ça :
En revanche, ce type de code fonctionne :
Je veux appeler useTransition
ailleurs que dans un composant
Vous ne pouvez pas appeler useTransition
hors d’un composant parce que c’est un Hook. Pour ce type de besoin, préférez la fonction autonome . Son fonctionnement est identique, à ceci près qu’elle ne fournit pas l’indicateur isPending
.
La fonction que je passe à startTransition
est exécutée immédiatement
Si vous exécutez ce code, ça affichera 1, 2, 3 :
C’est censé afficher 1, 2, 3. La fonction que vous passez à startTransition
ne doit pas être différée. Contrairement au setTimeout
du navigateur, la fonction de rappel n’est pas appelée plus tard. React exécute votre fonction immédiatement, mais les mises à jour d’état que vous y demandez pendant son exécution sont marquées comme étant des Transitions. Vous pouvez vous imaginer le fonctionnement suivant :