Les actions React 19 en pratique : à quoi servent useActionState, use() et le retirement du compilateur.
React 19 Actions élimine une grande partie du code : les gestionnaires de formulaire, les mises à jour optimistes, forwardRef et la mémorisation manuelle. À quoi servent useActionState, use() et les modifications apportées par le compilateur ?
Sources: React 19 Shipped Nine Months Ago. Most Teams Are Still Writing Code It Made Obsolete.
De nombreuses équipes ont simplement augmenté le numéro de version de React sans toucher au reste. Les indicateurs de chargement, le traitement des erreurs et les mises à jour optimistes qu’elles avaient écrits des années auparavant restent encore dans le code, car la mise à niveau ne les a jamais endommagés. Elle les a simplement rendus redondants. Voici un aperçu du code manuel que React 19 gère désormais à votre place.
Le schéma qui réapparaît constamment
Ouvrez n’importe quel composant de formulaire dans un projet React 19 et vous verrez la même structure. Il y a trois états : un pour l’état de chargement, un pour l’erreur et un pour le succès. Il existe un gestionnaire d’envoi asynchrone qui appelle e.preventDefault(), active l’indicateur de chargement, efface l’erreur précédente, attend la requête, active l’indicateur de succès dans un bloc try, copie le message dans la variable d’erreur dans un bloc catch, et désactive l’indicateur de chargement dans un bloc finally.
Cette méthode est restée la norme depuis que React est devenu populaire, et elle fonctionne bien. Dans React 19, elle est également devenue inutile. Un seul hook gère désormais le traitement des opérations en attente, des erreurs et des résultats, y compris l’ordre des requêtes séquentielles. La plupart des équipes ne l’ont jamais remarqué, car la mise à niveau ne nécessitait pas de changement.
Qu’est-ce qui est stable et qu’est-ce qui ne l’est pas
Un petit schéma d’abord, car certains articles décrivent des fonctionnalités comme déjà disponibles alors qu’elles ne le sont pas encore.
Disponible dans la version stable React 19.x :
- Les actions et les hooks qui s’y basent :
useActionState,useFormStatusetuseOptimistic. - L’API
use()permettant de lire des promesses et du contexte pendant le rendu. refen tant que propriété ordinaire, ce qui rendforwardRefobsolète.- Metadata natifs du document : les balises
<title>,<meta>et<link>générées à partir de composants. - Le React Compiler, qui a atteint la version 1.0 en octobre 2025 et prend en charge les versions allant jusqu’à React 17.
- Ajouts depuis la version 19.2 tels que
<Activity>etuseEffectEvent.
À l’heure de la rédaction, le composant <ViewTransition> ainsi que les Fragment Refs restent en version Canary ou expérimentale. Considérez comme obsolètes tous les éléments qui utilisent ces fonctionnalités déjà déployées, et consultez les notes de version de la version que vous installez réellement.
Actions : le nouveau modèle pour l’état asynchrone
L’idée fondatrice de React 19 est l’Action, une fonction asynchrone transmise à une transition. React s’occupe de tout ce qui l’entoure : l’état en attente, la gestion des erreurs, les mises à jour optimistes et le réinitialisation des formulaires, toutes choses que les équipes devaient auparavant écrire manuellement.
useActionState, useFormStatus et useOptimistic ne sont pas trois fonctionnalités indépendantes. Ce sont trois façons de voir ce même mécanisme.
useActionState remplace le schéma des trois indicateurs
Plutôt que d’utiliser les trois états loading, error et success, vous écrivez une fonction Action qui reçoit l’état précédent ainsi que les données du formulaire et renvoie l’état suivant. Vous la transmettez, avec un état initial, à useActionState. Ce hook renvoie trois éléments : l’état actuel, une fonction à fournir au formulaire, et un booléen isPending.
Le composant effectue alors trois actions simples. La propriété action du formulaire reçoit directement la fonction retournée. Le bouton est désactivé tant que isPending vaut vrai. De plus, tout message est lu à partir de l’état retourné. Il n’y a ni état de chargement, ni état d’erreur, ni try, catch ou finally, ni preventDefault, et pas de réinitialisation manuelle.
Le fait de passer une fonction à action est intentionnel. Les formulaires HTML disposent depuis toujours d’une propriété action, et React 19 l’a réintégrée. Cela permet un amélioration progressive, permettant à un formulaire d’être soumis même sans JavaScript, avec React qui améliore son comportement une fois les scripts chargés.
useFormStatus permet à un bouton de connaître son formulaire
La manière la plus pratique d’utiliser useFormStatus concerne un bouton de soumission réutilisable. À l’intérieur, l’hook renvoie un drapeau pending décrivant le formulaire parent, sans aucune propriété transmise. Le bouton se désactive et son étiquette est remplacée par quelque chose comme « Enregistrement » tant que le formulaire est en attente. Placez ce composant n’importe où à l’intérieur de n’importe quel formulaire, et il fonctionnera immédiatement, ce qui élimine le besoin de transmettre des propriétés à plusieurs niveaux pour une nécessité très courante. Une précaution : l’hook lit l’état du formulaire qui contient le composant, il doit donc être rendu à l’intérieur de ce formulaire, et non à côté.
useOptimistic permet de gérer facilement les retours en temps réel
Les mises à jour optimistes affichent immédiatement au utilisateur le résultat attendu, avant que le serveur ne le confirme, et se corrigent automatiquement en cas d’échec de la demande. Effectuées manuellement, elles nécessitent des IDs temporaires, une liste distincte des éléments en attente, une logique de fusion ainsi que du code de réversion dans une branche d’erreur. Il est facile de commettre des erreurs subtiles.
Avec useOptimistic, vous fournissez au hook la liste réelle ainsi qu’un petit réducteur décrivant comment ajouter un élément marqué comme en attente. À l’intérieur de l’action du formulaire, vous appelez le setter qu’il renvoie puis vous attendez que l’enregistrement soit effectué. L’interface affiche immédiatement le nouvel élément, éventuellement avec une opacité réduite tant qu’il est en attente. Lorsque l’action est terminée, les données réelles remplacent la copie optimiste, et si l’enregistrement échoue, React revient automatiquement à l’état précédent. Aucun bloc de gestion d’erreur ni réversion manuelle n’est nécessaire.
use(): lecture conditionnelle des ressources
use() est une nouvelle API qui lit une ressource, telle qu’une promesse ou un contexte, pendant le rendu. Contrairement à tous les autres hooks, elle peut être appelée de manière conditionnelle. Un composant peut lire les informations d’un utilisateur, retourner immédiatement lorsque les détails sont cachés, et ne lire les préférences qu’ensuite. Enveloppez l’arborescence dans un conteneur Suspense avec une solution de secours, et React suspendra le traitement jusqu’à ce que les données arrivent.
Une contrainte est importante : les promesses transmises à use() doivent rester stables d’un rendu à l’autre. Créez-les donc en dehors du composant, utilisez une couche de mise en cache comme React Query ou SWR, ou même un simple tableau au niveau du module indexé par ID. Une promesse recréée à chaque rendu fera apparaître indéfiniment la solution de secours à l’écran.
ref en tant que prop
Ce changement est simple. Les composants fonctionnels reçoivent désormais ref en tant que prop normal, ce qui vous permet de le transmettre à l’élément d’entrée sous-jacent sans envelopper le composant dans forwardRef. Le comportement reste identique, avec un wrapper en moins et une importation en moins. Le code existant utilisant forwardRef continue de fonctionner, puisque la suppression progressive est sans impact, mais les nouveaux composants ne devraient pas l’utiliser.
Le compilateur React
Le compilateur représente la mise à jour la plus discrète de toutes. Il analyse les composants au moment de la compilation et applique la mémoisation que les équipes gèrent généralement soit de manière incohérente avec useMemo, useCallback et React.memo, soit qu’elles omettent complètement. Vous écrivez simplement des composants et le compilateur insère correctement le mécanisme de mise en cache.
Pour l’essayer, installez le plugin Babel babel-plugin-react-compiler et ajoutez-le à la liste des plugins de votre configuration Babel. Comme il prend également en charge React 17 et 18, vous pouvez l’adopter sans d’abord mettre à jour React, ce qui aide les équipes bloquées par une mise à niveau mais souhaitant bénéficier des améliorations de performance.
Remarque de sécurité concernant les composants serveur
Des avertissements de sécurité liés aux refus de service et à la divulgation du code source ont affecté les paquets react-server-dom-* vers le début de 2026, et des versions corrigées ont été publiées pour chaque ligne prise en charge. Si vous utilisez les composants serveur React, vérifiez la version installée par rapport aux avertissements actuels et utilisez une version corrigée ou plus récente. Ne vous fiez pas à votre mémoire quant à la version considérée comme sûre.
Que faire cette semaine
- Nouveaux formulaires : utilisez dès le début
useActionStatepour définir une action, la transmettre au hook et lire la valeur deisPendingdans le résultat retourné, sans avoir recours à aucune flag manuelle. - Gestionnaires existants : ne réécrivez pas tout d’un coup. Choisissez-en un, convertissez-le en Action et observez son fonctionnement. L’amélioration en termes de lisibilité est généralement suffisamment évidente pour déterminer elle-même la priorité de la migration.
- Le compilateur : ajoutez-le à votre configuration de build. Il s’agit d’une petite modification, il fonctionne avec le code existant et n’exige aucune réécriture, ce qui en fait la solution la plus simple de l’époque React 19, offrant les effets les plus importants.
- Composants serveur : vérifiez votre version en fonction des correctifs de sécurité.
Les titres de l’article ont attiré l’attention lors de sa publication. Le véritable changement réside dans le fond : Actions en tant que modèle standard pour tout changement d’état asynchrone, ce qui élimine discrètement une grande partie du code que les développeurs React écrivent chaque jour. De nombreuses équipes ont mis à jour leurs outils, mais le code reste encore à adapter.