Comment passer à React 18 ?

Si vous vous demandez comment passer à React 18 et que vous n’êtes pas tout à fait sûr de ce qu’il faut faire, nous allons nous charger dans cet article de vous donner toutes les informations dont vous avez besoin pour effectuer le passage rapidement et facilement.

Vous voulez probablement faire la transition parce que vous savez déjà que React 18 a fait un excellent travail d’évolution du populaire framework de composants JavaScript et a ajouté tout un ensemble de nouvelles fonctionnalités construites autour du suspense et du rendu simultané. Entre autres choses, on nous promet de meilleures performances, ainsi que de plus grandes capacités et une expérience améliorée pour les développeurs.

Dans le guide que nous avons préparé pour vous cette fois-ci, nous allons vous montrer comment mettre à jour les bases de code qui sont présentes dans React 18. Veuillez noter que ce guide sert d’aperçu des changements qui peuvent être appliqués. La migration devrait se dérouler sans problème pour les petits projets qui suivent les meilleures pratiques de React, tandis que les projets plus importants avec des composants plus complexes peuvent présenter quelques complications, comme nous l’expliquerons plus loin dans l’article.

Comment passer à React 18

Étapes à suivre pour installer React 18

Avant toute chose, il est important de préciser que vous devez utiliser npm pour mettre à jour la dépendance React dans votre projet React 18 :

$ npm install react@latest react-dom@latest

Dans cette nouvelle version, vous ne devriez pas rencontrer d’incompatibilité avec les versions précédentes. Ainsi, les nouvelles fonctionnalités sont activées de manière opt-in. Comme aucune modification n’a encore été apportée au code, vous devriez pouvoir lancer l’application et constater que tout apparaît correctement. Le projet fonctionnera de manière optimale avec la version 17 de React.

$ npm start

Comment activer les nouvelles fonctionnalités de React 18 (nouvelle API racine)

Si vous utilisez React 18 sans aucune base de code, cela finira par provoquer quelques effets secondaires, notamment l’apparition d’un avertissement dans la console du navigateur chaque fois que l’application est en mode développeur :

ReactDOM.render n’est plus supporté dans React 18. Utilisez createRoot à la place. Jusqu’à ce que vous passiez à la nouvelle API, votre application se comportera comme si elle utilisait React 17.

Vous pouvez ignorer ce message si vous n’êtes pas encore prêt à mettre votre projet à niveau. Lorsque vous voudrez adopter les nouvelles fonctionnalités offertes par React 18, vous devrez effectuer une mise à niveau. L’ancienne fonctionnalité a déjà été remplacée par l’API racine, qui est davantage orientée objet.

La facilité d’utilisation a été améliorée, mais aussi un système de rendu simultané est activé qui sert à piloter toutes les nouvelles fonctionnalités de base de .ReactDOM.render().

Dans le fichier, vous devez rechercher les lignes suivantes ou des lignes qui ressemblent à ceci dans index.jsapp.js :

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. Cela représente une instance du composant importé comme élément racine de l’application. Le contenu rendu est celui de l’élément HTML avec .AppinnerHTMLid=»react».

Afin d’apporter une modification à l’API racine de React 18, vous devrez remplacer le code ci-dessus par le code suivant :

import App from «./App.js»;
import {createRoot} from «react-dom/client»;
const container = document.getElementById(«react»);
const root = createRoot(container);
root.render(<App />);

En exécutant le code ci-dessus, nous allons obtenir ce qui serait l’équivalent de l’API ci-dessus. Au lieu d’initialiser l’élément racine et d’effectuer le rendu de l’application comme une opération impérative, dans React 18, vous créez d’abord un objet racine, puis vous effectuez explicitement le rendu du contenu .ReactDOM.render().

Il suffit ensuite de rechercher dans le code la partie où le nœud racine est désassemblé. Maintenant, vous devrez modifier la nouvelle méthode dans l’objet racine ReactDOM.unmountComponentAtNode()unmount() :

// 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();

Modification des rappels de rendu

Dans le cas de l’argument de rappel de l’option de méthode, cela n’a pas de contrepartie directe dans l’API racine de React 18. Auparavant, vous pouviez utiliser ce code pour pouvoir vous connecter à la console une fois que React a fini de rendre le nœud ReactDOM.render()Rendered ! root node :

ReactDOM.render()Rendered!:
import App from «./App.js»;
import ReactDOM from «react-dom»;
const container = document.getElementById(«react»);
ReactDOM.render(<App />, container, () => console.log(«Rendered!»));

En fait, vous devez savoir que cette fonctionnalité a été supprimée car le moment de l’invocation du callback est imprévisible lors de l’utilisation des nouvelles fonctions de rendu du serveur de flux dans React 18. Dans le cas où vous utilisez déjà une callback de traitement et que vous devez maintenir la compatibilité, un comportement similaire peut être obtenu en utilisant le mécanisme de référence suivant :

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 !»)} />) ;

On peut dire que React appelle la fonction refs lorsque les différents composants sont montés. En fixant une référence sur le composant qui est un nœud racine, cela lui permet de détecter quand un rendu a lieu, donnant ainsi un effet assez similaire à l’ancien système de rappel de rendu.

Quels sont les problèmes de mise à jour du débogage ?

À ce stade, l’application devrait maintenant être rendue avec les fonctionnalités de React 18 et sans aucun avertissement de la console. Vous pouvez tester l’application de manière approfondie pour vous assurer que tout fonctionne toujours correctement. Si vous rencontrez des problèmes, vous pouvez les résoudre en utilisant les résolutions courantes suivantes.

Vérifier le <StrictMode>

Les applications qui sont enveloppées dans le composant ont la possibilité de se comporter différemment lorsqu’elles sont rendues en mode de développement React 18. Cela s’explique par le fait que le mode strict est désormais utilisé pour vérifier si la base de code prend en charge l’état réutilisable, un concept qui a été entièrement introduit dans React dans une future version <StrictMode>.

L’état réutilisable permet à React de réassembler un composant qui a été précédemment retiré au dernier état restauré automatiquement. Cela rend les composants résistants à la double invocation d’effets. Le mode strict peut maintenant vous aider à mieux vous préparer à l’état réutilisable simulé lors de l’assemblage, du désassemblage et du réassemblage des composants utilisés, ce qui peut poser des problèmes lorsque l’état précédent ne peut pas être restauré.

Vous devez savoir qu’il existe un moyen de désactiver le mode strict au cas où vous auriez des problèmes avec l’application ou avec des dépendances que vous n’êtes pas prêt à résoudre pour le moment.

Prise en charge du traitement par lots des mises à jour d’état

Un détail que nous pensons que vous devriez connaître est que React 18 modifie la façon dont les mises à jour de statut sont «mises en lots» afin d’améliorer les performances. Lorsque les valeurs changent d’état plusieurs fois dans une fonction, React tentera de les combiner en un seul re-rendu :

const Component = () => {
    const [query, setQuery] = useState(«»);
    const [queryCount, setQueryCount] = useState(0);
    /**
     * Two state updates, only one re-render
     */
    setQuery(«demo»);
    setQueryCount(queryCount + 1);

Il s’agit d’un mécanisme qui augmente l’efficacité, mais qui ne fonctionnait auparavant qu’à l’intérieur des gestionnaires d’événements React. Notez que React 18 fonctionne avec toutes les mises à jour d’état, même si elles proviennent de gestionnaires d’événements natifs, de délais d’attente, etc.

Notez également qu’une partie du code peut se comporter différemment de ce qui précède dans le cas de mises à jour consécutives du statut à l’un ou l’autre endroit.

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 avez la possibilité de désactiver ce comportement dans les situations où vous n’êtes tout simplement pas prêt à refactoriser votre code. Dans ce cas, vous devrez «envelopper» les mises à jour de statut pour les forcer à commiter immédiatement : flushSync()

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}`);
        });
    }
};

N’utilisez pas les fonctionnalités qui ont été supprimées et qui ne sont pas prises en charge

Lorsque tous les aspects ci-dessus ont été avortés, l’application devrait être compatible avec React 18. Bien que dans certains cas, il y ait plus de changements à la surface de l’API, ceux-ci ne devraient pas vraiment affecter la plupart des applications. Voici quelques-unes de celles que nous pensons que vous devriez connaître :

  • unstable_changedBits a été supprimé : il s’agit d’une API non prise en charge qui vous permettait auparavant de ne pas recevoir de mises à jour de contexte. Il n’est actuellement pas disponible.
  • Le polyfill Object.assign() a été supprimé : il est nécessaire d’ajouter manuellement le paquet polyfill object-assign dans le cas où vous avez besoin que de très vieux navigateurs soient supportés sans un fichier object-assign() intégré.
  • Internet Explorer n’est pas pris en charge : React a officiellement pris soin de supprimer la prise en charge d’Internet Explorer avant la fin de la prise en charge du navigateur en juin. Il n’est pas nécessaire d’effectuer une mise à niveau vers React 18 si vous souhaitez toujours que l’application s’exécute dans ce navigateur.
  • L’utilisation de Suspenbse avec un backend non défini est maintenant équivalente à null : un détail important à noter est que les limites de suspension ont été omises, permettant au code de «cascader» vers la prochaine limite majeure dans l’arbre. Ainsi, React 18 respecte désormais les composants suspendus sans support .fallback={undefined}.

Une représentation côté serveur

Les applications qui utilisent la représentation côté serveur devront apporter quelques modifications afin de fonctionner correctement avec React 18.

Dans la ligne avec la nouvelle API racine, vous devez remplacer l’ancienne fonction du code côté client par la nouvelle fonction fournie par le paquet : hydrate()hydrateRoot()react-dom/client

// 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 le code du serveur, vous devrez remplacer les API de rendu obsolètes par les nouvelles contreparties. Dans presque tous les cas, vous devez passer au nouveau. Dans les nouvelles API de streaming, vous débloquez l’accès aux capacités de rendu du serveur de streaming de React 18, où le serveur a la capacité de continuer à fournir de nouveaux HTML au navigateur après le rendu initial de l’application .renderToNodeStream()renderToReadableStream().

Commencer à utiliser les nouvelles fonctionnalités de React 18

À ce stade, vous devriez déjà avoir effectué la mise à niveau vers React 18, et vous pouvez donc commencer à utiliser les nouvelles fonctionnalités puissantes offertes par cette nouvelle version. Notez que l’utilisation simultanée de React signifie que les rendus des composants peuvent être interrompus, ce qui débloque de nouvelles capacités et des interfaces utilisateur plus réactives.

Il convient de noter que certaines des fonctionnalités ajoutées comprennent des mises à jour importantes de Suspense, désignant ainsi la priorité des mises à jour de l’état des Transitions et le mécanisme intégré pour limiter le retraitement causé par des mises à jour non urgentes, mais à haute fréquence.

D’autre part, il y a aussi plusieurs changements et améliorations, comme le fait que nous avons maintenant la possibilité de retourner à la méthode d’un composant et de retirer plusieurs nouveaux attributs HTML, qui sont reconnus par le rendu de React Dom.undefinedrender()setState()imageSizesimageSrcSetaria-description.

Conclusion

Enfin, il devrait être clair que React 18 est stable et entièrement prêt à être utilisé par tout utilisateur qui souhaite profiter des avantages qu’il offre. Dans la grande majorité des cas, le processus de mise à niveau devrait être rapide et facile, car il ne nécessite qu’une mise à jour de npm et un changement de la nouvelle API racine. Cependant, tous ses composants doivent encore être testés, car vous devez savoir qu’il peut se comporter différemment dans certains cas, comme dans le cas du mode strict ou lorsque le traitement automatique par lots est appliqué.

Sans aucun doute, nous pouvons dire que cette nouvelle version indique l’orientation future de React en tant que nouveau framework performant pour toutes les applications web. Nous pouvons également dire que nous obtenons également beaucoup de capacités de rendu côté serveur de React, en ajoutant Suspense côté serveur et la possibilité de continuer à diffuser aux utilisateurs après le rendu initial. Ceci est très utile pour donner aux développeurs plus de flexibilité lorsqu’il s’agit d’obtenir une meilleure distribution du rendu du client et du serveur.