Comment mettre à niveau vers React 18
React 18 fait évoluer le framework de composants JavaScript populaire avec de nouvelles fonctionnalités construites autour du rendu simultané et du suspense. Il promet de meilleures performances, plus de fonctionnalités et une expérience de développement améliorée pour les applications qui effectuent le changement.
Dans cet article, nous vous montrerons comment mettre à niveau vos bases de code existantes vers React 18. Gardez à l’esprit que ce guide n’est qu’un aperçu des modifications les plus largement applicables. La migration devrait être assez simple pour les petits projets qui suivent déjà les meilleures pratiques de React ; de grands ensembles de composants complexes peuvent poser des problèmes, que nous détaillerons ci-dessous.
Sommaire
Installation de React 18
Avant de faire quoi que ce soit d’autre, utilisez npm pour mettre à niveau la dépendance React de votre projet vers la v18 :
$ npm install react@latest react-dom@latest
La nouvelle version n’a techniquement aucune incompatibilité descendante. Les nouvelles fonctionnalités sont activées sur une base opt-in. Comme vous n’avez pas encore modifié de code, vous devriez pouvoir démarrer votre application et observer son rendu correctement. Votre projet fonctionnera avec son comportement React 17 existant.
$ npm start
Activation des fonctionnalités de React 18 : la nouvelle API racine
L’utilisation de React 18 sans aucune modification de la base de code entraînera un effet secondaire : vous verrez un avertissement de la console du navigateur chaque fois que votre application sera montée en mode développement.
ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17.
Ce message d’obsolescence peut être ignoré en toute sécurité si vous n’êtes pas prêt à mettre à niveau votre projet. Lorsque vous souhaitez adopter les fonctionnalités de React 18, vous devez apporter la modification décrite. L’ancien ReactDOM.render()
a été remplacée par une nouvelle API racine plus orientée objet. Outre une facilité d’utilisation améliorée, il active également le système de rendu simultané qui alimente toutes les nouvelles fonctionnalités de titre.
Au sein de votre index.js
ou app.js
file, recherchez les lignes qui ressemblent à celles-ci :
import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(<App />, container);
Il s’agit d’un point d’entrée typique pour une application React. Il rend une instance de l’importé App
composant comme élément racine de votre application. Le contenu rendu est déposé en tant que innerHTML
de l’élément HTML avec id="react"
.
Pour passer à l’API racine de React 18, remplacez le code ci-dessus par ce qui suit :
import App from "./App.js"; import {createRoot} from "react-dom/client"; const container = document.getElementById("react"); const root = createRoot(container); root.render(<App />);
Cela a un effet équivalent à l’ancien ReactDOM.render()
API. Au lieu d’initialiser un élément racine et de rendre votre application en une seule opération impérative, React 18 vous oblige à créer d’abord un objet racine, puis à rendre explicitement votre contenu.
Recherchez ensuite les endroits de votre code où vous démontez votre nœud racine. Changer ReactDOM.unmountComponentAtNode()
au nouveau unmount()
méthode sur votre objet racine :
// Before import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(<App />, container); ReactDOM.unmountComponentAtNode(container); // After import App from "./App.js"; import {createRoot} from "react-dom/client"; const container = document.getElementById("react"); const root = createRoot(container); root.render(<App />); root.unmount();
Remplacement des rappels de rendu
La ReactDOM.render()
L’argument de rappel facultatif de la méthode n’a pas d’équivalent direct dans l’API racine de React 18. Vous pouviez auparavant utiliser ce code pour vous connecter Rendered!
à la console après que React a fini de rendre le nœud racine :
import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(<App />, container, () => console.log("Rendered!"));
Cette fonctionnalité a été supprimée car le moment de l’invocation du rappel est imprévisible lors de l’utilisation des nouvelles fonctionnalités d’hydratation partielle et de rendu du serveur de streaming de React 18. Si vous utilisez déjà des rappels de rendu et que vous devez maintenir la compatibilité, vous pouvez obtenir un comportement similaire en utilisant le mécanisme refs :
import {createRoot} from "react-dom/client"; const App = ({callback}) => ( <div ref={callback}> <h1>Demo App</h1> </div> ); const container = document.getElementById("react"); const root = createRoot(container); root.render(<App callback={() => console.log("Rendered!")} />);
React appelle les références de fonction lorsque les composants sont montés. La définition d’une référence sur le composant qui est votre nœud racine vous permet de détecter le moment où le rendu se produit, fournissant un effet similaire à l’ancien système de rappel de rendu.
Débogage des problèmes de mise à niveau
Votre application devrait maintenant être rendue à l’aide des fonctionnalités de React 18 et sans aucun avertissement de la console. Testez soigneusement votre application pour vous assurer que tout fonctionne toujours comme prévu. Si vous rencontrez des problèmes, vous pourrez peut-être les résoudre avec ces résolutions courantes.
Vérifier
Applications enveloppées dans le <StrictMode>
Le composant peut se comporter différemment lors du rendu en mode développement de React 18. En effet, le mode strict teste désormais si votre base de code prend en charge l’état réutilisable, un concept qui sera entièrement introduit dans React dans une future version.
L’état réutilisable permet à React de remonter un composant précédemment supprimé avec son dernier état automatiquement restauré. Cela nécessite que vos composants soient résistants à la double invocation d’effets. Le mode Strict vous aide désormais à vous préparer à l’état réutilisable en simulant le montage, le démontage et le remontage de vos composants à chaque fois qu’ils sont utilisés, en faisant apparaître tous les problèmes où l’état précédent ne peut pas être restauré. Vous pouvez désactiver le mode strict s’il détecte des problèmes dans votre application ou ses dépendances que vous n’êtes pas prêt à résoudre.
Prise en charge du lot de mise à jour de l’état
React 18 modifie la façon dont les mises à jour d’état sont « groupées » pour améliorer les performances. Lorsque vous modifiez plusieurs fois les valeurs d’état dans une fonction, React essaie de les combiner en un seul rendu :
const Component = () => { const [query, setQuery] = useState(""); const [queryCount, setQueryCount] = useState(0); /** * Two state updates, only one re-render */ setQuery("demo"); setQueryCount(queryCount + 1); };
Ce mécanisme augmente l’efficacité mais ne fonctionnait auparavant qu’à l’intérieur des gestionnaires d’événements React. Avec React 18, cela fonctionne avec toutes les mises à jour d’état, même si elles proviennent de gestionnaires d’événements natifs, de délais d’attente ou de promesses. Certains codes peuvent se comporter différemment si vous effectuez des mises à jour d’état consécutives à l’un de ces emplacements.
const Component = () => { const [query, setQuery] = useState(""); const [queryId, setQueryId] = useState(""); const [queryCount, setQueryCount] = useState(0); const handleSearch = query => { fetch(query).then(() => { setQuery("demo"); setQueryCount(1); // In React 17, sets to "query-1" // In React 18, sets to "query-0" - previous state update is batched with this one setQueryId(`query-${queryCount}`); }); } };
Vous pouvez désactiver ce comportement dans les situations où vous n’êtes pas prêt à refactoriser votre code. Enveloppez les mises à jour d’état dans flushSync()
pour les forcer à s’engager immédiatement :
const Component = () => { const [query, setQuery] = useState(""); const [queryId, setQueryId] = useState(""); const [queryCount, setQueryCount] = useState(0); const handleSearch = query => { fetch(query).then(() => { flushSync(() => { setQuery("demo"); setQueryCount(1); }); // Sets to "query-1" setQueryId(`query-${queryCount}`); }); } };
Arrêtez d’utiliser les fonctionnalités supprimées et non prises en charge
Une fois que tous les aspects ci-dessus ont été traités, votre application devrait être entièrement compatible avec React 18. Bien qu’il y ait quelques modifications supplémentaires de la surface de l’API, celles-ci ne devraient pas affecter la majorité des applications. En voici quelques-uns à connaître :
unstable_changedBits
a été retiré – Cette API non prise en charge permettait de désactiver les mises à jour de contexte. Il n’est plus disponible.- La
Object.assign()
polyfill a été supprimé – Vous devez ajouter manuellement leobject-assign
package polyfill si vous avez besoin de prendre en charge de très anciens navigateurs sansObject.assign()
. - Internet Explorer n’est plus pris en charge – React a officiellement abandonné la compatibilité avec Internet Explorer avant la fin du support du navigateur en juin. Vous ne devez pas mettre à niveau vers React 18 si vous avez toujours besoin que votre application s’exécute dans IE.
- Utiliser le suspense avec un
undefined
fallback équivaut maintenant ànull
– Limites de suspense avecfallback={undefined}
étaient précédemment ignorées, permettant au code de cascader à la limite parent suivante dans l’arborescence. React 18 respecte désormais les composants Suspense sans repli.
Rendu côté serveur
Les applications qui utilisent le rendu côté serveur nécessiteront quelques modifications supplémentaires pour fonctionner avec React 18.
En ligne avec la nouvelle API racine, vous devez remplacer l’ancienne hydrate()
fonction dans votre code côté client avec le nouveau hydrateRoot()
fourni par le react-dom/client
forfait:
// Before import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.hydrate(<App />, container); // After import App from "./App.js"; import {createRoot} from "react-dom/client"; const container = document.getElementById("react"); const root = hydrateRoot(container, <App />);
Dans votre code côté serveur, remplacez les appels d’API de rendu obsolètes par leurs nouveaux homologues. Dans la plupart des cas, vous devez changer renderToNodeStream()
au nouveau renderToReadableStream()
. Les nouvelles API de flux déverrouillent l’accès aux capacités de rendu du serveur de streaming de React 18, où le serveur peut continuer à fournir du nouveau code HTML au navigateur après le rendu initial de votre application.
Commencez à utiliser les fonctionnalités de React 18
Maintenant que vous avez effectué la mise à niveau, vous pouvez commencer à rendre votre application plus puissante en incorporant les fonctionnalités de React 18. L’utilisation de la simultanéité par React signifie que les rendus des composants peuvent être interrompus, débloquant de nouvelles fonctionnalités et des interfaces utilisateur plus réactives.
Certaines des fonctionnalités ajoutées incluent des mises à jour majeures de Suspense, un moyen de désigner la priorité des mises à jour d’état avec les transitions et un mécanisme intégré de limitation des rendus provoqués par des mises à jour non urgentes mais à haute fréquence. Il y a aussi plusieurs modifications et améliorations diverses : vous pouvez revenir undefined
d’un composant render()
méthode, l’avertissement concernant l’appel setState()
sur les composants non montés a été supprimé, et plusieurs nouveaux attributs HTML tels que imageSizes
, imageSrcSet
et aria-description
sont reconnus par le moteur de rendu de React DOM.
Sommaire
React 18 est stable et prêt à l’emploi. Dans la plupart des cas, le processus de mise à niveau doit être rapide et facile, ne nécessitant qu’une mise à jour npm et un passage à la nouvelle API racine. Cependant, vous devez toujours tester tous vos composants : ils peuvent se comporter différemment dans certaines situations, comme en mode strict ou lorsque le traitement par lots automatique s’applique.
Cette nouvelle version indique l’orientation future de React en tant que framework hautes performances pour toutes sortes d’applications Web. Il étend également les capacités de rendu côté serveur de React, en ajoutant Suspense sur le serveur et la possibilité de continuer à diffuser du contenu à vos utilisateurs après le rendu initial. Cela donne aux développeurs plus de flexibilité pour distribuer le rendu sur le client et le serveur.