Rendu et Commit – React
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)

Déclenchement 
Rendu 
Commit
É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 :
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.)

Une mise à jour d'état… 
…déclenche… 
…un rendu !
É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.
Piège
Le rendu doit toujours être un calcul pur :
- Mêmes entrées, mêmes sorties. Pour les mêmes données en entrée, un composant devrait toujours produire le même JSX. (Lorsque vous commandez une salade de tomates, vous ne devriez pas voir arriver une salade de concombres !)
- On se mêle de ses affaires. Un composant ne devrait pas modifier des objets ou variables qui existaient avant le rendu. (Une commande donnée ne devrait pas changer la commande de quelqu’un d’autre.)
En enfreignant ces règles, attendez-vous à des bugs déroutants et des comportements inattendus au fil de la croissance de votre base de code. Lorsqu’on développe en « Mode Strict », React appelle deux fois la fonction de chaque composant, ce qui aide à repérer les erreurs dues à des fonctions « impures ».
En détail
Optimiser les performances
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 :
Ç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.

En résumé
- Toute mise à jour à l’écran dans une appli React se déroule en trois temps :
- Déclenchement
- Rendu
- Commit
- Vous pouvez tirer parti du Mode Strict pour repérer les erreurs dans vos composants
- React ne touchera pas au DOM si le résultat du rendu est identique d’une fois sur l’autre