Rendu et Commit
Avant que vos composants ne soient affichés à l’écran, React doit en effectuer le rendu. Bien comprendre les étapes de ce processus vous aidera à réfléchir à l’exécution de votre code de façon à en expliquer le comportement.
Vous allez apprendre
- Ce que signifie « rendu » en React
- Quand et pourquoi React fait le rendu d’un composant
- Les étapes nécessaires à l’affichage d’un composant à l’écran
- Pourquoi le rendu n’entraîne pas toujours une mise à jour du DOM
Imaginons que vos composants soient les membres d’une brigade de cuisine, qui confectionnent de savoureux plats à partir d’ingrédients de base. Dans ce cas, React serait le serveur qui transmet les commandes des clients et leur ramène leurs plats. Ce processus de requêtes et réponses liées à l’interface utilisateur (UI pour User Interface, NdT) comporte trois étapes :
- Le déclenchement du rendu (on transmet la commande du client à la cuisine)
- Le rendu du composant (on prépare la commande en cuisine)
- Le commit (la retranscription des changements) dans le DOM (on amène les plats sur la table)
Illustré par Rachel Lee Nabors
Étape 1 : déclenchement d’un rendu
Il y a deux déclencheurs possibles pour le rendu d’un composant :
- On est sur le rendu initial du composant.
- Dans le composant (ou un de ses ancêtres), l’état local a été mis à jour.
Rendu initial
Lorsque votre appli démarre, vous devez déclencher le rendu initial. Les frameworks et bacs à sable masquent parfois le code qui en est responsable, mais ça se fait en appelant createRoot
avec le nœud DOM cible, puis en appelant la méthode render
avec votre composant :
import Image from './Image.js'; import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')) root.render(<Image />);
Essayez de commenter l’appel à root.render()
pour voir votre composant disparaître !
Nouveaux rendus suite à des mises à jour d’état
Une fois que le composant a fait son rendu initial, vous pouvez déclencher des rendus supplémentaires en mettant à jour son état au moyen d’une fonction set
. Mettre à jour l’état local d’un composant met automatiquement un rendu en file d’attente. (C’est un peu comme le convive d’un restaurant qui commanderait du thé, un dessert et plein d’autres choses après avoir passé sa commande initiale, en fonction de l’état de sa faim et de sa soif.)
Illustré par Rachel Lee Nabors
Étape 2 : rendu des composants par React
Après que vous avez déclenché un rendu, React appelle vos composants pour déterminer ce qu’il doit afficher à l’écran. Le « rendu », c’est React qui appelle vos composants.
- Lors du rendu initial, React appelle le composant racine.
- Lors des rendus suivants, React appellera les fonctions composants dont une mise à jour de l’état local a déclenché le rendu.
Ce processus est récursif : si le composant mis à jour renvoie un autre composant, React fera le rendu de ce composant-là ensuite, et si ce dernier renvoie à son tour un autre composant, il fera le rendu de ce composant-là, et ainsi de suite. Le processus continue jusqu’à ce qu’il ne reste plus de composants imbriqués à traiter, pour que React sache exactement ce qu’il doit afficher à l’écran.
Dans l’exemple qui suit, React appellera Gallery()
, puis plusieurs fois Image()
:
export default function Gallery() { return ( <section> <h1>Sculptures inspirantes</h1> <Image /> <Image /> <Image /> </section> ); } function Image() { return ( <img src="https://i.imgur.com/ZF6s192.jpg" alt="Floralis Genérica' par Eduardo Catalano : une sculpture de fleur métallique gigantesque avec des pétales réfléchissants." /> ); }
- Lors du rendu initial, React créera les nœuds DOM pour les balises
<section>
,<h1>
et les trois<img>
. - Lors des rendus ultérieurs, React déterminera si certaines de leurs propriétés ont changé depuis le rendu précédent. Il gardera cette information au chaud jusqu’à l’étape suivante : la phase de commit.
En détail
Le comportement par défaut, qui fait le rendu de tous les composants enveloppés par le composant mis à jour, n’est pas optimal pour les performances lorsque le composant mis à jour est situé très haut dans l’arbre. Si vous constatez un souci avéré de performances, vous disposez de plusieurs options à mettre en place explicitement pour résoudre ça ; elles sont décrites dans la section Performance. Évitez les optimisations prématurées !
Étape 3 : commit dans le DOM par React
Après avoir fait le rendu de vos composants (c’est-à-dire après avoir appelé leurs fonctions), React devra mettre à jour le DOM.
- Lors du rendu initial, React utilisera l’API DOM
appendChild()
pour retranscrire à l’écran tous les nœuds DOM qu’il a créés. - Lors des rendus ultérieurs, React s’attachera à effectuer le strict minimum d’opérations nécessaires (qu’il aura déterminées lors de la phase de rendu !) pour mettre le DOM en correspondance avec le résultat du dernier rendu en date.
React ne modifie les nœuds DOM que s’il y a un écart d’un rendu à l’autre. Par exemple, voici un composant qui refait son rendu avec des props différentes passées depuis son parent à chaque seconde. Remarquez que vous pouvez ajouter du texte dans l’<input>
, modifier sa value
, mais le texte ne disparaît pas quand le composant refait son rendu :
export default function Clock({ time }) { return ( <> <h1>{time}</h1> <input /> </> ); }
Ça fonctionne parce qu’à l’étape précédente (le rendu), React n’a mis à jour que le contenu du <h1>
, avec le nouveau time
. Il constate qu’un <input/>
est présent dans le JSX au même endroit que la dernière fois, avec les mêmes props (il n’en a pas), aussi React ne touche-t-il pas à l’<input/>
—encore moins à sa value
!
Épilogue : dessin par le navigateur (Browser Paint)
Une fois que React a mis à jour le DOM en se basant sur les résultats du rendu, le navigateur va devoir redessiner l’écran. Même si ce procédé est souvent appelé « rendu » (“rendering”, NdT), nous parlerons plutôt dans cette documentation de « dessin » (“painting”, NdT) pour éviter toute confusion.
Illustré par Rachel Lee Nabors