Comment lier React et le DOM ?

TLDR;

  • Pour lier une application React au DOM, il faut utiliser le package ReactDOM et la fonction render avec en paramètres, le composant racine de l’application et le noeud du DOM auquel il sera rattaché.

ReactDOM.render( <MonApplication />, document.getElementById('root') );

Lier React au DOM

Pour que notre application soit effectivement affichée dans le DOM, nous allons utiliser le package ReactDOM.
Ce package va tout simplement nous permettre de “monter” notre application React sur un élément du DOM (ici un élément qui possède l’id “root”) :

1
2
3
4
ReactDOM.render(
<MonApplication />,
document.getElementById('root')
);

La méthode renderprend donc 2 paramètres, l’élément React, racine de notre application et le noeud du DOM sur lequel est attaché l’élément React. Avec ça, votre application React va apparaître dans votre navigateur (si il n’y pas d’erreurs bien sûr :) ).

C’est aussi simple que ça !

Mais, nous nous formons à une librairie dédiée à la création d’application web et paradoxalement, ce n’est qu’après plusieurs chapitres que le DOM est abordé, plutôt étrange non ? Il y a bien une raison.

Le virtual DOM

React implémente un concept très intéressant : le virtualDOM. Un concept qui va nous permettre de réaliser des applications web complexes et rapides !

Le DOM

Tout d’abord, qu’est-ce que le DOM ?

Le DOM est l’API qui permet de manipuler le contenu hiérarchisé de notre page web (du HTML donc) sous forme d’arbre. Les éléments HTML constituent les noeuds de cet arbre.

Les limites

Un arbre, c’est pratique à parcourir, un peu moins à modifier (supprimer, ajouter des éléments) mais surtout, modifier le DOM implique le recalcule de la disposition et style de chacun des éléments de la page, conduisant à de sérieux problèmes de performance lorsque l’on réalise de nombreuses modifications.

Comment React tente de contrer cette limitation ?

React et le DOM

Voici une définition d’un élément React :

“Un élement React est léger, sans état, immutable et constitue une représentation virtuel d’un élément DOM.”
source : https://gist.github.com/sebmarkbage/fcb1b6ab493b0c77d589

Ainsi, lorsque l’on crée un élement <App/>, le composant racine de notre application React, on crée une copie simplifiée de l’application dans le “vrai” DOM, on parle de Virtual DOM.

Comment le virtual DOM fonctionne ?

On l’a déjà dit, manipuler le DOM est lent, React va donc optimiser les appels au DOM que l’on va réaliser. Entre deux mises à jour, React va comparer le nouveau et l’ancier DOM virtuels de l’application et réaliser une comparaison, appelée réconciliation.

Grace à ça, nous n’avons jamais besoin de réfléchir à la façon dont notre UI doit se mettre à jour, React gère ça dans sont coin et va intelligemment cibler les noeuds du DOM où des modifications s’imposent et les appliquer, limitant ainsi les recalculs de layout de notre page. Un gain de temps de calcul très intéressant pour réaliser des applications rapides !

Tout l’intérêt du DOM virtuel réside dans le fait que manipuler un DOM virtuel est rapide puisque l’on manipule des objets JavaScript, rien ne se retrouve effectivement dessiner sur l’écran.

Pour imager, cela revient à modifier la disposition des pièces d’un appartement sur un plan. C’est simple et rapide, bien plus en tout cas que de bouger les pièces d’un vrai appartement…. :)

Comment le virtualDOM sait qu’il doit être mis à jour ?

Pour modifier l’état interne d’un composant, nous avons vu qu’il fallait impérativement appeler la méthode setState. Nous allons maintenant comprendre pourquoi.

A chaque fois que setState est appelé dans un composant, ce composant et tous les enfants de ce composant (qui reçoivent donc les props du composant modifié en cascade) vont devoir redéfinir leur affichage en conséquence et donc être redessinés.

Voici un schéma expliquant l’impact de setState sur l’arbre des composants d’une application React:


source : http://techblog.constantcontact.com/software-development/reactive-component-based-uis/

Un composant dans lequel setState est appelé va donc modifier son noeud respectif dans le DOM virtuel ainsi que celui de tous ses enfants amenant à la mise à jour du DOM dans le navigateur.

On voit ici que setState a un très grand rôle puisque, si il sert effectivement à manipuler l’état interne d’un composant, il met également en marche tout le mécanisme permettant la mise à jour de l’UI via la comparaison des DOM virtuels, opération non neutre en terme de temps de calcul. Aussi, dans un but d’optimisation, React va regrouper certaines opérations d’update pour par exemple, ne réaliser qu’une seule comparaison d’arbres alors que 100 setState ont été appelés en très peu de temps dans différents composants. Si cette optimisation est pratique en terme de performance, elle peut être déroutante pour le développeur.

Exemple:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class App extends React.Component {
constructor() {
this.state = { counter: 1 };
}
onClick() {
this.setState({ counter: 2 });
//Affiche : le compteur vaut: 1
console.log('le compteur vaut: ' + this.state.counter);
}
render() {
return (
<div
onClick={this.onClick}
>
{this.state.counter}
</div>
);
}
}

Cette exemple met en avant le fait que setState ne se comporte pas de façon synchrone, il faut donc le manipuler en gardant ça en tête. Pour contrer ce problème, la fonction setState peut prendre en deuxième argument un callback qui sera appelé une fois le state mis à jour.

La fonction onClick de l’exemple précédent serait modifiée comme tel:

this.setState({ counter: 2 }, () => console.log('le compteur vaut: ' + this.state.counter));

Dans cet article, nous avons vu qu’il était très simple de lier une application React au DOM. De plus, en filant la réflexion, nous avons pu appréhender en partie la “magie” de React et la raison pour laquelle la fonction setState peut être déroutante lorsqu’on la manipule.