React 19
(github.com/facebook)19.0.0 (5 décembre 2024)
Nouvelles fonctionnalités
React
- Actions :
startTransitionpeut désormais accepter des fonctions asynchrones. Ces fonctions sont appelées « Actions » et permettent de mettre à jour l’état en arrière-plan puis de valider l’UI en une seule fois. Les Actions peuvent exécuter des effets de bord comme des requêtes asynchrones, et la Transition attend la fin du travail avant de se terminer. useActionState: nouveau hook permettant d’ordonner les Actions dans une Transition et d’accéder à l’état. Il accepte un état initial et un reducer.useOptimistic: nouveau hook permettant de mettre à jour l’état pendant qu’une Transition est en cours. Une fois la Transition terminée, l’état est mis à jour avec la nouvelle valeur.use: nouvelle API permettant de lire des ressources pendant le rendu. Elle accepte une Promise ou un Context, et si une Promise est fournie, le rendu est suspendu jusqu’à la résolution de la valeur.- Utiliser
refcomme prop : il est désormais possible d’utiliser ref comme prop sans avoir besoin deforwardRef. - Préchauffage des siblings Suspense : lorsqu’un composant est suspendu, React valide immédiatement le fallback de la frontière Suspense la plus proche.
Client React DOM
- Prop
actionde<form>: les Form Actions gèrent automatiquement les formulaires et s’intègrent àuseFormStatus. Le formulaire est automatiquement réinitialisé en cas de succès. - Prise en charge des métadonnées du document : il est possible de rendre nativement les balises de métadonnées du document depuis les composants.
- Prise en charge des feuilles de style : insère les feuilles de style dans le
<head>du client avant de révéler le contenu d’une frontière Suspense. - Prise en charge des scripts asynchrones : il est possible de rendre des scripts asynchrones depuis n’importe où dans l’arbre de composants.
Serveur React DOM
- Ajout des API
prerenderetprerenderToNodeStream: API destinées à la génération de sites statiques, conçues pour fonctionner dans des environnements de streaming comme les flux Node.js et les flux web.
Composants serveur React
- Fonctionnalités RSC : les directives, les composants serveur et les fonctions serveur sont désormais stabilisés. Les bibliothèques incluant des composants serveur peuvent maintenant cibler React 19 comme dépendance pair.
Obsolescences prévues
- Accès à
element.ref: l’accès àelement.refest déprécié au profit deelement.props.ref. react-test-renderer: dans React 19,react-test-rendererémet un avertissement de dépréciation et bascule vers le rendu concurrent pour l’usage web.
Changements majeurs
React
- Nouvelle transformation JSX requise : la nouvelle transformation JSX est nécessaire pour améliorer la taille des bundles et permettre l’utilisation de JSX sans importer React.
- Les erreurs de rendu ne sont plus relancées : si une erreur n’est pas interceptée par un Error Boundary, elle est signalée à
window.reportError. - Suppression de
propTypes: l’utilisation depropTypesest désormais ignorée silencieusement. Une migration vers TypeScript est recommandée. - Suppression de
defaultPropspour les fonctions : les paramètres par défaut ES6 peuvent être utilisés à la place. - Suppression des refs de type chaîne : l’utilisation des refs sous forme de chaînes doit être migrée vers des callbacks de ref.
React DOM
- Suppression de
react-dom/test-utils:acta été déplacé dereact-dom/test-utilsversreact. Les autres utilitaires ont été supprimés. - Suppression de
ReactDOM.render,ReactDOM.hydrate: remplacés parReactDOM.createRootetReactDOM.hydrateRootpour le rendu concurrent.
Changements notables
React
- Utiliser
<Context>comme provider : il est désormais possible de rendre<Context>comme provider à la place de<Context.Provider>. - Prise en charge des éléments personnalisés : React 19 réussit désormais tous les tests des custom elements.
- Changements dans StrictMode :
useMemoetuseCallbackréutilisent maintenant le résultat de mémoïsation du premier rendu.
React DOM
- Différences pour les erreurs d’hydratation : en cas de divergence, React 19 consigne une seule erreur incluant les différences du contenu non concordant.
Changements TypeScript
- Retours implicites interdits : les refs n’acceptent désormais que des fonctions de nettoyage. Les retours implicites provoquent maintenant une erreur.
- Argument initial requis pour
useRef: l’argument initial est désormais obligatoire. - Typage plus strict de
ReactElement: les props des éléments React utilisent désormaisunknownpar défaut au lieu deany.
1 commentaires
Avis sur Hacker News
Je ne comprends pas vraiment pourquoi autant de gens ici détestent React
J’ai commencé ma carrière avec Laravel et du JS pur, et depuis que j’ai essayé React, créer des apps évolutives me paraît réaliste, et le front-end est même devenu amusant
Même quand on change d’entreprise, React se reprend facilement, et grâce au support de TypeScript et à son vaste écosystème, j’ai l’impression qu’on peut construire et faire grandir à peu près n’importe quoi assez facilement
Je ne comprends pas non plus pourquoi les nouvelles fonctionnalités font peur aux gens. On peut toujours créer des SPA ou faire comme avant ; c’est un peu comme quand les bases NoSQL, Spring Boot ou Kotlin sont arrivés : si on ne voulait pas les utiliser, on ne les utilisait pas
Je croyais aussi que Jetpack Compose et SwiftUI s’étaient inspirés de React ; il me semble avoir vu ça autrefois dans la documentation Android, mais je n’arrive plus à le retrouver
Cela dit, je n’ai pas encore des dizaines d’années d’expérience, donc je ne sais pas à quel point les grandes équipes d’autrefois s’amusaient en construisant de grosses web apps comme Airbnb avec jQuery ou du JS pur. Aujourd’hui, j’ai même du mal à imaginer comment gérer l’état, manipuler le DOM et traiter les effets de bord en JS pur
Peut-être qu’un jour, moi aussi, je râlerai contre un nouveau framework en disant que React, c’était mieux
L’argument est souvent du genre : « le front-end court toujours après le nouveau truc brillant, et React en fait partie », mais React existe depuis 2013 et est assez mainstream depuis environ 2015
On dit aussi que les frameworks et les bibliothèques ajoutent de la complexité, mais quand on demande précisément quelle complexité, on obtient rarement une réponse. Si l’on crée une application significative sans framework, on finit par inventer son propre framework, moins maintenable, moins testable et moins documenté
Les étapes de compilation et de bundling sont aussi souvent critiquées, mais aujourd’hui il existe des frameworks éprouvés comme Expo, Next.js ou Meteor, si bien qu’il n’y a presque plus de raison d’écrire soi-même sa configuration webpack ou son pipeline de build
La tendance à imposer des frameworks web partout a produit, ces dix dernières années, une foule de sites lents et fragiles, souvent surconçus sans offrir une expérience utilisateur nettement meilleure qu’en 2008
Pour certains développeurs front-end, quelle que soit la question, la réponse est une combinaison de React / Node / Vite / Angular / Vue / Nuxt / Next / Bun / Deno / Svelte / SvelteKit, et si possible le tout doit tourner sur des dizaines de swarms Docker dominés par Kubernetes. C’est du genre : « Tu veux mettre ton CV en ligne ? Alors passons les trois prochaines semaines à dessiner le diagramme de flux d’état de l’app »
Si React reçoit particulièrement des critiques, c’est probablement parce que ceux qui suivent les modes des frameworks sont déjà passés au prochain truc brillant, tandis que ceux qui détestaient déjà ce genre de frameworks continuent de les détester ; il ne reste donc plus grand monde pour défendre ce bazar. Les autres frameworks semblent promis au même destin avec le temps
Leur fonctionnement réel est beaucoup caché, peu intuitif, il est facile de se tromper et d’écrire des UI peu performantes
Il faut sans cesse réfléchir à ce qui s’exécute combien de fois, à ce qu’il faut mettre dans le tableau de dépendances, à ce qu’il faut mettre dans
useCallbacketuseEffect, ce qui crée une forte charge cognitiveUne partie de la communauté recommande même des dépendances React inutiles dans les projets, ce qui ne fait qu’ajouter de l’overhead et de la complexité
Il est aussi facile de mélanger logique métier et logique d’UI
Pendant un temps, les SPA avaient des inconvénients par rapport aux MPA, mais avec les standards web modernes et l’arrivée du rendu côté serveur dans les frameworks SPA, ces problèmes sont aujourd’hui presque tous résolus
https://www.youtube.com/watch?v=b2F-DItXtZs
C’est une belle release, mais je me dis aussi que les personnes qui se lancent maintenant dans le développement frontend ne sont pas vraiment à envier
Des explications du genre « un nouveau hook pour ordonner les Actions dans une Transition, accéder à l’état de l’action et à l’état pending, qui reçoit un reducer capable d’appeler l’Action ainsi qu’un état initial utilisé au premier rendu, et accepte aussi une chaîne optionnelle destinée à prendre en charge l’amélioration progressive des formulaires lorsqu’il est passé à la prop action du form » donnent l’impression que la fonctionnalité est intéressante, mais c’est beaucoup trop verbeux
Si je commençais aujourd’hui à développer des sites web, je ne saurais probablement pas par où commencer
Cela dit, React reste un excellent framework, et cette release est une amélioration. La critique ne vise pas seulement React, mais plutôt le développement frontend dans son ensemble
Le bon vieux rendu côté serveur avec quelque chose comme HTMX est bien mieux
J’ai gagné ma vie pendant 4 ans avec du développement frontend React et j’ai créé mon premier site web en 2005 ; aujourd’hui, je migre un projet client de React vers HTMX, et je trouve ça bien supérieur
Moins de bugs, moins de pièges dus à une mauvaise utilisation des hooks
Si j’avais besoin de rendu côté client, j’utiliserais Solid ou Vue, mais j’éviterais React. Si vous n’avez pas le choix, bonne chance
Les prémisses de base — liaison unidirectionnelle, DOM virtuel, rerendering et calcul de diff — ne m’ont jamais vraiment convaincu. Cela revient à doubler l’utilisation mémoire du navigateur et à effectuer un rerendering complet avec calcul de diff à chaque interaction
À l’époque, la réponse était « rendons-le d’abord fiable, puis rendons-le rapide », mais aujourd’hui il est rempli de structures bricolées pour le rendre rapide, sans être ni rapide ni fiable
Un framework honnête à liaison bidirectionnelle garantit au moins la rapidité, et la fiabilité vient avec l’expérience, selon moi. React est simplement confus. Je plains les ingénieurs dont la première initiation au frontend a été React : désapprendre et réapprendre doit être bien plus difficile qu’apprendre
Après être passé par VBScript, JS, jQuery, Mootools, Applets, ActionScript, YUI/Ext/Sencha, Backbone, Knockout, Angular 1, Angular 2, React et Vue 1, j’aurais envie de recommander d’essayer Flutter. C’est vraiment rafraîchissant
Le problème, c’est Dart. Si Flutter avait été en TypeScript, il aurait été un peu plus proche de l’idéal, mais Dart continue d’entretenir l’esprit de churn sans fin du frontend
Les standards du web, dans l’ensemble, sont eux aussi plus stables que jamais. Les jeunes développeurs n’ont plus besoin d’apprendre des centaines d’astuces de layout pour que les pages s’affichent correctement dans plusieurs navigateurs, et il faut même moins souvent des hacks pour cibler un seul navigateur
Je comprends la fatigue liée à JavaScript, mais je pense que c’est l’une des meilleures périodes pour apprendre
L’ensemble m’a donné l’impression de faire du vrai développement correctement structuré, et comparé à ce qu’il y avait avant, c’était comme une bouffée d’air frais
Pour 99 % des développeurs, ce genre de fonctionnalité n’est pas nécessaire tant que l’application n’a pas atteint une certaine taille, et peut-être jamais. React ne l’impose pas non plus
J’ai autrefois aimé les frameworks côté client comme React, mais j’ai fini par comprendre qu’ils avaient ajouté de la complexité partout où c’était possible
Le backend, le frontend, la stack DevOps : la complexité s’est glissée partout, et davantage de couches continueront d’être ajoutées pour synchroniser cette complexité distribuée
Le fait que l’UI se rerende automatiquement quand les données ou le modèle changent va dans le bon sens
On peut débattre des détails, mais modifier impérativement l’UI à la main à chaque changement de données ne tient pas très longtemps à l’échelle d’une base de code ou d’une équipe
On a ajouté une complexité énorme pour faire rendre au navigateur web des boîtes d’une manière pour laquelle il n’était pas conçu à l’origine, et au nom d’un changement de paradigme de programmation, on a aussi beaucoup perdu en productivité et en outillage
Il y avait de belles idées et de belles implémentations, mais je ne sais pas si cela en valait la peine. Je me demande même si ce n’était pas une sorte de dispositif de sécurité de l’emploi
Ce n’est pas un problème propre à ReactJS : tout l’écosystème JavaScript est devenu fou avec les bibliothèques et les outils, mais React était particulièrement pénible à prendre en main, au point qu’il a fallu créer create react app pour pouvoir faire une application hello world dans un délai raisonnable
J’ai cessé d’espérer comprendre pourquoi l’API des composants à classes a été remplacée par les hooks
On peut choisir un framework plus simple, ou éviter l’orchestration serveur
Si l’on n’a pas le choix, on peut aussi lancer soi-même un projet en pariant qu’une stack simple donnera un avantage d’efficacité
L’un des meilleurs aspects de cette release est que ref peut désormais être utilisé comme prop.
forwardRefn’est donc plus nécessaireL’article de blog est plus lisible : https://react.dev/blog/2024/12/05/react-19
updateNamerenvoie une erreur dansconst error = await updateName(newName);À la manière de JS/TS, ne pourrait-il pas simplement lancer une
Error?Si, jusqu’ici, « redux » est mentionné 7 fois dans les 45 commentaires, j’aimerais ici citer Jotai comme représentant de la famille Recoil. Il y a de bonnes chances qu’il fonctionne déjà avec React 19 sans modification particulière
Quand la complexité frontend devient suffisamment importante, les autres outils de gestion d’état finissent souvent par gêner plus que nécessaire
Si vous en êtes venu à détester React, mais qu’en réalité vous êtes surtout épuisé par le mur sans fin de constantes d’action, la plomberie des props, la lutte contre les providers/contexts imbriqués et la fuite vers le pub-sub, ça vaut le coup d’essayer quelque chose comme Jotai
https://github.com/pmndrs/zustand
https://github.com/pmndrs/valtio
Jotai me donne l’impression d’imposer trop de boilerplate manuel, et Valtio repose sur beaucoup de « magie » via les proxies ; même si je l’aime bien personnellement, je ne suis pas sûr que ce soit un bon choix pour une équipe
Zustand se situe à mi-chemin entre boilerplate et magie, c’est donc celui que nous avons choisi pour le gros projet en cours
Quand j’ai commencé à travailler sur des apps React il y a quelques années, tous les packages de gestion d’état que je voyais en étaient remplis, et c’est toujours le cas aujourd’hui
Au final, pour m’en éloigner et me concentrer sur le travail, j’ai créé ma propre solution [1], qui fonctionne bien en production. C’est dommage qu’il n’existe pas d’option populaire qui fonctionne de façon similaire
[1] https://github.com/facepunch/react-class-model
Le bon côté des context hooks, c’est qu’ils sont composables, et combinés à des requêtes mises en cache, ils permettent de créer un pattern assez maintenable
Je me demande quelle amélioration concrète Jotai apporte ici
J’espère vraiment ne plus jamais avoir à gérer redux ni sagas
Je n’aime pas la plupart des nouvelles fonctionnalités introduites
Actions et les hooks
useActionState/useOptimisticressemblent à un gros piège à complexité. Le hookusea un nom bien trop peu informatif, et il ne gère pas les promises créées à l’intérieur d’un composantIl y a sûrement de bonnes raisons, mais passer une promise en prop puis la traiter avec le hook
useme semble devoir créer plus de complexité que les contournements actuelsLes Server Components ont aussi l’air assez complexes, et je suis content de ne pas encore avoir à m’en occuper
L’amélioration des messages d’erreur d’hydration est bienvenue, et les changements permettant d’utiliser les providers différemment ainsi que les refs comme props sont de bonnes améliorations de qualité de vie
Globalement, pour créer des SPA, j’aime React/Preact. Avec une bibliothèque de composants riche en fonctionnalités comme MUI et une solution simple de gestion d’état comme Preact Signals, créer une SPA reste assez intuitif
Mais je m’inquiète de voir la complexité s’insinuer petit à petit. Rien qu’en lisant les descriptions des nouveaux hooks dans les notes de version, la charge cognitive paraît élevée
En revanche, React Compiler est un outil vraiment nécessaire. Il évitera aux programmeurs d’écrire eux-mêmes les optimisations classiques à l’intérieur des composants, ce qui devrait les rendre moins complexes
J’attends sa sortie et son intégration avec Vite et autres, et d’après ce que j’ai entendu, Preact devrait aussi être pris en charge
Ce serait bien de renommer l’API
useavec un nom différent du préfixe commun des hooksQuelqu’un qui débute avec les hooks React risque d’être dérouté en voyant que
usepeut être appelé conditionnellement, alors que les hooks ordinaires ne le peuvent pasJe suis vraiment content que la release ait été retardée pour résoudre le problème de Suspense parallèle
Je ne l’ai pas encore essayé, mais j’ai de grandes attentes, et dans l’ensemble c’est une excellente release
Dernière minute : prise en charge complète des custom elements. Autrement dit, des Web Components