Nouveautés de React 16
Ça fait maintenant plus d'un an qu'on attendait avec impatience la nouvelle version majeure de React. La version 16 est enfin arrivée ! Au programme, une meilleure gestion des erreurs, les portails, de meilleures performances et beaucoup d'autres nouveautés !
Nouveaux types retournés par les composants
Les tableaux
Les composants peuvent maintenant renvoyer des tableaux d'éléments sans avoir besoin de les englober dans un élément parent. Chaque élément doit avoir un attribut "key" pour éviter le fameux message d'alerte "key warning" 😒. Ça peut paraître tout simple, mais c'était une des fonctionnalités les plus attendues ! Bientôt, une syntaxe particulière permettra à JSX de ne plus avoir besoin de clé, on attend ça avec impatience 🎉.
render() {
return [
<li key="A">Edouard</li>,
<li key="B">Paul</li>,
<li key="C">Emmanuel</li>,
];
}
Les chaînes de caractères
Les composants peuvent maintenant rendre des chaînes de caractères, fini les <span>
inutiles !
render() {
return 'Smooth message !'
}
Meilleur gestion des erreurs
Jusqu'à présent, une erreur dans un composant se traduisait par plusieurs choses :
- Une erreur incompréhensible dans la console ㊙️
- Un state complément incohérent dans votre application 💥
- Un utilisateur qui se disait "ça ne marche pas 😤"
Partant du constat qu'une erreur isolée ne devrait pas empêcher le reste de l'application de fonctionner, React 16 a introduit un nouveau concept : les error boundaries.
Error boundaries
Les error boundaries sont des composants React qui ont pour responsabilité de capturer les erreurs de leurs enfants. Sont concernées les erreurs générées pendant le rendu, le cycle de vie d'une méthode ou la construction de leurs sous-arbres. Vous pouvez penser les error boundaries comme des try-catch sous forme de composants React.
Il est désormais possible de catcher un erreur et de la gérer de manière propre pour l'utilisateur.
Créer un error boundary
Pour créer un error boundary, il vous suffit d'implémenter la méthode suivante dans votre composant componentDidCatch(error, info)
:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
// Mise à jour du state
this.setState({ hasError: true });
// Il est aussi possible de loguer l'erreur
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// A vous de choisir la meilleure façon de gérer l'erreur
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Vous pouvez alors l'utiliser comme un composant classique, les erreurs de <MyWidget>
seront catchées par <ErrorBoundary>
.
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
Portails
React 16 expose une API permettant de gérer la problématique des portails. Si vous avez déjà eu à réaliser des modales, pop-ins, tooltips ou tout autre élément de type overlay en React, vous devez probablement être en train de sauter de joie 😄.
Avant React 16, il existait une méthode obscure appelée ReactDOM.unstable_renderSubtreeIntoContainer
qui permettait de créer un portail tout en conservant le contexte de son application. Cette API est aujourd'hui publique sous la forme de ReactDOM.createPortal
. Elle vous permet de rendre vos composants React dans un autre élément HTML de la page.
render() {
// React fait le rendu de ce composant dans votre <div id="my-modal" />
return ReactDOM.createPortal(
this.props.children,
document.getElementById('my-modal'),
);
}
Vous vous demandez sûrement à quoi ça peut servir ? Le principal use-case est un contournement des limites du CSS. Vous pouvez avoir besoin de rendre une modale à la racine du <body>
pour qu'elle s'affiche au dessus de tous les autres éléments. Mais on vous l'accorde, c'est tout de même réservé à un usage avancé.
Meilleur rendu côté serveur
React 16 inclut un nouveau moteur de rendu côté serveur. Plus rapide, il supporte aussi le streaming. React ne se base plus sur process.env
(qui est apparemment très lent). Vous n'avez plus besoin de faire un build production de React pour avoir de bonnes performances de rendu côté serveur !
React 16 est aussi meilleur pour ré-hydrater le code généré par le serveur. Il n'y a plus besoin d'avoir un exac-match entre le rendu côté serveur et le rendu côté client. React essaie désormais de réutiliser autant de DOM existant que possible. Résultat, un code plus propre et plus de checksums ! Même si en général, il n'est pas recommandé d'avoir des rendus différents côté serveur et côté client.
Support des attributs custom
React ne filtre plus les attributs inconnus, ils seront désormais présents dans le DOM. Ce filtre nécessitait une longue white-list et donc beaucoup d'octets.
Grâce à ça, la taille de librairie est réduite d'environ 32% par rapport à React 15. Sachant que React est un incontournable pour le chargement de votre application, c'est toujours bon à prendre. Voici les changements :
- react : 5,4 ko (gzip : 2,2 ko), au lieu de 20,7 ko
- react-dom : 103.7 ko (gzip : 32,6 ko), au lieu de 141 ko
- react + react-dom : 109 ko (gzip : 34,8 ko), au lieu de 161,7 ko
Cette différence s'explique aussi en grande partie par un changement de packaging. React utilise désormais Rollup, qui permet d'avoir un bundle plus flat. Le parsing est également plus rapide, on obtient de meilleures performances au chargement.
Licence MIT
C'était le sujet chaud de l'été pour la commuauté React. Comme promis dans l'article précédent, React 16 est sous licence MIT 😍 !
D'ailleurs, React 15.6.2 est aussi passé sous licence MIT.
Nouvelle architecure : Fiber
React 16 est basé sur une nouvelle architecture : "Fiber". C'est notamment cette architecture qui a permis de développer les nouvelles fonctionnalités. Dans les prochaines versions, Fiber permettra à React de progresser plus rapidement.
Une des plus belles fonctionnalités promises par Fiber, c'est le rendering asynchrone. Grâce à ça, React ne bloque plus le thread principal. En d'autres termes vos animations ne freezeront plus même si vous affichez de nombreux éléments dans le DOM.
Si vous voulez avoir une idée de ce que ça donne, Andrew Clark a fait une démo. Pour bien la comprendre, regardez attentivement le comportement du petit carré qui tourne en haut à droite. C'est une animation CSS comme vous pourriez en avoir dans votre application.
Ever wonder what "async rendering" means? Here's a demo of how to coordinate an async React tree with non-React work https://t.co/3snoahB3uV pic.twitter.com/egQ988gBjR
— Andrew Clark (@acdlite) 18 septembre 2017
Aujourd'hui, React fait le rendu de manière synchrone, on voit l'animation se figer. Le CPU est occupé à faire le rendu et ne peut pas s'occuper d'animer en même temps. Avec le rendu asynchrone, il n'y a plus de coupure, React laisse le temps à l'animation de s'exécuter et défère légèrement le rendering. Grâce à Fiber il sera également possible d'attendre que le rendu soit complètement exécuté, afin d'éviter l'effet blink pour l'utilisateur.
React 16 comble les derniers défauts majeurs de React. Avec l’introduction de Fiber, et le passage en licence MIT, c’est un nouveau départ qui s’annonce pour React. On attend avec impatience les nouvelles fonctionnalités et le rendu asynchrone !