React v16.0
Nous sommes ravis d’annoncer la sortie de React v16.0 ! On y trouve notamment quelques fonctionnalités attendues de longue date, telles que les fragments, les périmètres d’erreurs, les portails, la prise en charge des attributs DOM personnalisés, un rendu côté serveur amélioré et une taille de fichier réduite.
Nouveaux types de retour pour render
: fragments et chaînes
Vous pouvez désormais renvoyer un tableau d’éléments depuis la méthode render
d’un composant. Comme pour tous les tableaux, vous devrez ajouter une prop key
à chaque élément afin d’éviter l’avertissement associé :
render() {
// Pas besoin d’enrober cette liste par un élément dédié !
return [
// Mais n’oubliez pas les clés :)
<li key="A">Premier élément</li>,
<li key="B">Deuxième élément</li>,
<li key="C">Troisième élément</li>,
];
}
À partir de React 16.2.0, nous ajouterons la prise en charge d’une syntaxe spéciale de fragments dans JSX, qui n’exigera pas de clés.
Nous avons aussi ajouté la possibilité de renvoyer des chaînes de caractères :
render() {
return 'Regarde maman, sans les spans !';
}
Consultez la liste intégrale des types de retour autorisés.
Meilleure gestion des erreurs
Jusque-là, les erreurs à l’exécution lors du rendu pouvaient laisser React dans un état bancal, entraînant des messages d’erreurs cryptiques et nécessitant un rafraîchissement de la page pour revenir à la normale. Pour y remédier, React 16 utilise une stratégie de gestion d’erreurs plus robuste. Par défaut, lorsqu’une erreur est levée au sein du rendu d’un composant ou d’une de ses méthodes de cycle de vie, l’arborescence de composants complète est démontée de la racine. On évite ainsi d’afficher des données corrompues. Cependant, ça ne constitue pas une expérience utilisateur idéale.
Au lieu de démonter l’appli entière à chaque fois qu’une erreur survient, vous pouvez recourir aux périmètres d’erreurs. Les périmètres d’erreurs sont des composants spéciaux qui capturent les erreurs survenant dans leur sous-arbre, et affichent alors une interface utilisateur (UI) de repli. Vous pouvez considérer les périmètres d’erreurs comme des instructions try
-catch
, mais pour les composants React.
Pour en apprendre davantage, jetez un coup d’œil à notre précédent article sur la gestion d’erreurs avec React 16.
Portails
Les portails fournissent un moyen officiel d’afficher des enfants dans un nœud DOM situé hors de la hiérarchie DOM du composant parent.
render() {
// React *ne crée pas* une nouvelle div. Il affiche les enfants dans `domNode`.
// `domNode` peut être n’importe quel nœud DOM valide, où qu’il soit dans le DOM.
return ReactDOM.createPortal(
this.props.children,
domNode,
);
}
Vous pouvez consulter un exemple complet dans la documentation des portails.
Meilleur rendu côté serveur
React 16 inclut un moteur de rendu côté serveur (Server-side rendering ou SSR, NdT) intégralement réécrit. Il est très rapide. Il prend en charge le streaming, ce qui vous permet de commencer à envoyer du contenu à votre client plus tôt. Et grâce à notre nouvelle stratégie de packaging qui précompile les vérifications basées sur process.env
(figurez-vous que lire process.env
dans Node.js est super lent !), vous n’avez plus besoin de bundler React pour obtenir de bonnes performances de rendu côté serveur.
Sasha Aickin, membre de l’équipe noyau de React, a écrit un super article au sujet des améliorations du SSR dans React 16 (en anglais). Selon ses méthodes de mesure, le rendu côté serveur avec React 16 est à peu près trois fois plus rapide qu’avec React 15. « Lorsqu’on compare avec React 15 qui précompilerait les lectures de process.env
, on constate une accélération d’environ 2,4x avec Node 4, de 3x avec Node 6, et carrément de 3,8x avec la nouvelle version 8.4 de Node. Et si vous comparez avec React 15 sans précompilation, React 16 accélère par un ordre de magnitude le SSR avec la dernière version de Node ! » (Comme le fait remarquer Sasha, gardez à l’esprit que ces chiffres sont basés sur des mesures de situations artificielles, et que vous pourriez avoir des résultats différents sur des applications réelles.)
Qui plus est, React 16 hydrate mieux le HTML rendu côté serveur lorsque celui-ci atteint le client. Il n’exige plus que le rendu initial client corresponde exactement à celui issu du serveur. Au lieu de ça, il essaiera de réutiliser au maximum le DOM existant. Plus de sommes de contrôle ! D’une façon générale, nous déconseillons de faire des rendus distincts entre serveur et client, mais ça peut s’avérer utile dans certains cas (ex. les horodatages). Il est toutefois dangereux d’avoir des nœuds manquants côté serveur, car ça pourrait entraîner la création de nœuds aux attributs incorrects au même niveau du DOM.
Consultez la documentation de ReactDOMServer
pour en apprendre davantage.
Prise en charge des attributs DOM personnalisés
Au lieu d’ignorer les attributs HTML et SVG non reconnnus, React les transfèrera désormais au DOM. Ça présente l’avantage supplémentaire de permettre la purge de l’essentiel de la liste blanche d’attributs de React, ce qui réduit au passage les tailles des fichiers.
Taille de fichier réduite
En dépit de toutes ces nouveautés, React 16 est en fait plus petit que la 15.6.1 !
react
fait 5.3 Ko (2.2 Ko gzippé), au lieu de 20.7 Ko (6.9 Ko gzipped).react-dom
fait 103.7 Ko (32.6 Ko gzippé), au lieu de 141 Ko (42.9 Ko gzippé).react
+react-dom
font 109 Ko (34.8 Ko gzippé), au lieu de 161.7 Ko (49.8 Ko gzippé).
Ça correspond au total à une réduction de 32% de la taille, comparé à la version précédente (30% après gzip).
Cette différence de taille est en partie attribuable à des changements de stratégie de packaging. React utilise désormais Rollup pour créer des bundles plats pour chaque type de distribution, ce qui à la fois réduit la taille et améliore les performances d’exécution. Ce format à plat permet aussi à React d’impacter de façon similaire la taille de votre bundle, indépendamment de la façon dont vous livrez votre propre appli, que vous utilisiez Webpack, Browserify, les bundles UMD officiels, ou tout autre mécanisme.
Licence MIT
Au cas où vous l’auriez raté, React 16 est désormais disponible sous licence MIT. Nous avons également publié la 15.6.2 sous MIT, pour celles et ceux qui ne peuvent pas mettre à jour immédiatement.
Nouvelle architecture du noyau
React 16 est la première version de React basée sur notre nouvelle architecture noyau, dont le nom de code est “Fiber”. Vous pouvez tout savoir sur ce projet en consultant le blog d’ingénierie de Facebook. (Divulgâcheur : nous avons réécrit React !)
Fiber est responsable de la plupart des nouveautés de React 16, telles que les périmètres d’erreurs et les fragments. Dans les prochaines versions, attendez-vous à davantage de nouvelles fonctionnalités tandis que nous continuerons à libérer davantage le véritable potentiel de React.
Le domaine le plus enthousiasmant sur lequel nous travaillons est sans doute le rendu asynchrone, une stratégie de planification coopérative du travail de rendu qui permet de rendre périodiquement la main au navigateur. Le principal avantage, avec le rendu asynchrone, c’est que les applis deviennent plus réactives, car React évite de bloquer le thread principal.
La démo ci-dessous fournit un premier aperçu des types de problématiques que résout le rendu asynchrone :
Vous vous êtes déjà demandé ce que « rendu asynchrone » signifie ? Voici une démo sur la coordination entre une arborescence asynchrone React et du travail hors-React https://t.co/3snoahB3uV pic.twitter.com/egQ988gBjR (en anglais)
— Andrew Clark (@acdlite) 18 septembre 2017
Astuce : soyez attentif·ve au carré noir qui tourne.
Nous estimons que le rendu asynchrone sera très important, et représente l’avenir de React. Pour faciliter autant que possible la migration vers la v16.0, nous n’activons pas encore les fonctionnalités asynchrones, mais nous avons hâte de commencer à les rendre disponibles au cours des prochains mois. Restez à l’écoute !
Installation
React v16.0.0 est disponible sur le référentiel npm.
Pour installer React 16 avec Yarn, exécutez :
yarn add react@^16.0.0 react-dom@^16.0.0
Pour installer React 16 avec npm, exécutez :
npm install --save react@^16.0.0 react-dom@^16.0.0
Nous fournissons aussi des builds UMD de React via un CDN :
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
Consultez la documentation pour des instructions d’installation détaillées.
Mise à jour
Bien que React 16 inclue des modifications internes majeures, en termes de mise à jour, vous pouvez la considérer comme n’importe quelle autre version majeure de React. Nous utilisons React 16 sur Facebook et Messenger.com depuis plus tôt cette année, et avons pu tirer parti de plusieurs versions beta et candidates pour éliminer des problèmes résiduels. À de rares exceptions près, si votre appli fonctionne avec React 15.6 sans avertissements, elle devrait marcher avec la 16.
Pour les dépréciations listées dans Packaging ci-après, des codemods (outils de migration automatique du code) sont fournis qui transformeront automatiquement votre code déprécié. Consultez l’article sur la 15.5.0 pour en apprendre davantage, ou parcourez les codemods disponibles sur le projet react-codemod.
Nouvelles dépréciations
Hydrater un conteneur rendu côté serveur nécessite désormais une API explicite. Si vous dynamisez du HTML rendu côté serveur, utilisez ReactDOM.hydrate
au lieu de ReactDOM.render
. Continuez à utiliser ReactDOM.render
si vous faites uniquement le rendu côté client.
React Addons
Comme annoncé précédemment, nous avons cessé de prendre en charge React Addons. Nous estimons que la dernière version en date de chaque addon (à l’exception de react-addons-perf
, voir plus loin) devrait continuer à fonctionner dans un avenir proche, mais nous ne les maintiendrons plus.
Consultez l’annonce précédente pour y trouver des suggestions de migration.
react-addons-perf
ne fonctionne plus du tout avec React 16. Il est probable que nous en publierons une nouvelle version à l’avenir. Dans l’intervalle, vous pouvez utiliser les outils de performance de votre navigateur pour profiler vos composants React.
Ruptures de compatibilité ascendante
React 16 comporte quelques petites ruptures de compatibilité. Elles concernent uniquement des cas à la marge et ne devraient pas impacter la majorité des applis.
- React 15 avait une prise en charge partielle et non documentée des périmètres d’erreurs au travers de
unstable_handleError
. Cette méthode a été renomméecomponentDidCatch
. Vous pouvez utiliser un codemod pour migrer automatiquement vers la nouvelle API. ReactDOM.render
etReactDOM.unstable_renderSubtreeIntoContainer
renvoient désormaientnull
si on les appelle depuis une méthode de cycle de vie. Pour contourner ça, vous pouvez recourir aux portails ou aux refs.-
setState
:- Appeler
setState
avecnull
ne déclenche plus de mise à jour. Ça vous permet de décider dans une fonction de mise à jour si vous souhaitez déclencher un rendu ou non. - Appeler
setState
directement depuisrender
entraîne systématiquement une mise à jour. Ce n’était pas toujours le cas par le passé. Quoi qu’il en soit, vous ne devriez pas appelersetState
depuisrender
. - Les fonctions de rappel de
setState
(son second argument) sont désormais déclenchées immédiatement aprèscomponentDidMount
/componentDidUpdate
, plutôt qu’après le rendu de l’ensemble des composants.
- Appeler
- Si React remplace
<A />
par<B />
,B.componentWillMount
aura toujours lieu avantA.componentWillUnmount
. Auparavant,A.componentWillUnmount
était appelé en premier dans certains cas. - Jusqu’ici, modifier la
ref
d’un composant en détachait toujours la ref avant que lerender
du composant soit appelé. Nous ajustons désormais la ref plus tard, en appliquant les modifications au DOM. - Il est dangereux de refaire un rendu dans un conteneur qui a été modifié par autre chose que React. Ça fonctionnait jusqu’ici dans certains cas, mais restait totalement officieux. Nous émettons désormais un avertissement dans un tel cas. Vous devriez plutôt nettoyer les arborescences DOM de vos composants à l’aide de
ReactDOM.unmountComponentAtNode
. En voici un exemple. - La méthode de cycle de vie
componentDidUpdate
ne reçoit plus le paramètreprevContext
. (Voir #8631.) - Le moteur de rendu superficiel n’appelle plus
componentDidUpdate
parce que les refs DOM n’y sont pas disponibles. On est désormais cohérents aveccomponentDidMount
(qui n’était pas appelé non plus dans les anciennes versions). - Le moteur de rendu superficiel n’implémente plus
unstable_batchedUpdates
. ReactDOM.unstable_batchedUpdates
n’accepte plus qu’un argument supplémentaire après la fonction de rappel.
Packaging
- On ne trouve plus
react/lib/*
etreact-dom/lib/*
. Même dans les environnements CommonJS, React et ReactDOM sont précompilés vers des fichiers uniques (« bundles à plat »). Si vous vous reposiez jusque-là sur des éléments internes non documentés de React, et que ces aspects ne fonctionnent plus, créez un ticket spécifique pour nous en parler, et nous verrons si nous pouvons vous proposer une stratégie de migration. - Il n’y a plus de build
react-with-addons.js
. Tous les addons compatibles sont publiés séparément sur npm, et fournissent des fichiers uniques pour leurs versions navigateur si vous en avez besoin. - Les dépréciations introduites dans les versions 15.x ont été retirées du paquet noyau.
React.createClass
est désormais disponible danscreate-react-class
,React.PropTypes
dansprop-types
,React.DOM
dansreact-dom-factories
,react-addons-test-utils
dansreact-dom/test-utils
, et le moteur de rendu superficiel dansreact-test-renderer/shallow
. Consultez les articles de 15.5.0 et 15.6.0 pour apprendre comment migrer votre code à l’aide de codemods automatisés. -
Les noms et chemins des builds navigateurs mono-fichier ont changé pour accentuer la distinction entre les builds de développement et ceux de production. Par exemple :
react/dist/react.js
→react/umd/react.development.js
react/dist/react.min.js
→react/umd/react.production.min.js
react-dom/dist/react-dom.js
→react-dom/umd/react-dom.development.js
react-dom/dist/react-dom.min
.js →react-dom/umd/react-dom.production.min.js
Exigences vis-à-vis de l’environnement JavaScript
React 16 requiert les types de collections natifs Map et Set. Si vous prenez en charge des navigateurs et périphériques plus anciens qui pourraient ne pas les fournir nativement (par exemple IE < 11), envisagez l’inclusion d’un polyfill global dans votre application bundlée, tel que core-js ou babel-polyfill.
Un environnement polyfillé pour React 16 utilisant core-js pour autoriser des navigateurs plus anciens pourrait ressembler à ceci :
import 'core-js/es6/map';
import 'core-js/es6/set';
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Bonjour, monde !</h1>,
document.getElementById('root')
);
React utilise aussi requestAnimationFrame
(même dans les environnements de test).
Vous pouvez utiliser le module raf pour simuler requestAnimationFrame
:
import 'raf/polyfill';
Remerciements
Comme toujours, cette version n’aurait pas été possible sans nos contributeur·rice·s open source. Un immense merci à toutes les personnes qui ont créé des tickets, ouvert des PR, répondu aux tickets, écrit de la documentation, et plus encore !
Un remerciement tout spécial aux contributeurs noyau, en particulier pour leurs efforts héroïques des dernières semaines en préparation de cette sortie : Brandon Dail, Jason Quense, Nathan Hunzaker, et Sasha Aickin.