Si vous me suivez sur Twitter, vous avez surement remarqué que je poste de plus en plus de liens en relation avec ReactJS.
Laissez-moi vous guider et découvrir ce qui se cache sous ce drôle de nom.
ReactJS est une bibliothèque pour créer des interfaces utilisateurs. Cela peut vous paraître super pompeux comme ça, mais c'est pourtant dans ce domaine qu'il excelle.
Nous n'avons pas à faire ici à un framework complet comme l'est Angular par exemple. Par ailleurs, je ne rentrerais pas dans le débat (qui commence à faire long feu) qui compare ReactJS à Angular. Chacuns a ses avantages et ses inconvénients, et ils ne remplissent pas les mêmes besoins.
Maintenant que la potentielle flame war est éteinte, revenons à ReactJS.
React est donc une bibliothèque JS développée par Facebook, qui a pas mal le vent en poupe ces derniers temps, et est utilisée par les grands de ce monde. Jugez plutôt par vous même :
Facebook l'utilise depuis 2011 en interne et l'a appliqué massivement pendant la refonte d'Instagram (suite à son rachat) Autant dire qu'en développant et utilisant son propre outil depuis ces quelques années, React a déjà gagné ses lettres de noblesse.
Parlons maintenant un peu de ce qu'est réellement React.
En simplifiant, on pourrait dire que React ne s'occupe que du V de MVC. Ainsi, React n'a ni Controllers, ni Directive, ni Templates et encore moins de Global event listener. En fait, React n'a que des composants. Et d'ailleurs, il est dans la logique des choses de faire des composants qui réutilisent d'autres composants. Comme ça, vous découpez au maximum vos interfaces, et pouvez réutiliser les parties codées.
Pas de template donc, juste un assemblage de composants.
D'ailleurs, voici à quoi ressemble un composant bête et méchant en React :
Un composant est donc une classe qui doit à minima posséder une méthode render() C'est cette méthode render qui s'occupera du rendu de votre composant. Bien entendu, cette classe peut être enrichie de bien d'autres méthodes, propre à votre code ou bien propre à React.
Petit apparté au passage : Il est possible de faire du React de plusieurs manières. Soit vous codez en ES5, et dans ce cas là, vous n'avez pas vraiment de classe en JS, soit vous vous simplifiez la vie, et vous passez directement en ES6 pour avoir un support des classes en JS. Pour ma part, j'ai goûté à l'ES6, et autant que possible, je ne retournerais pas en ES5. Fin de lÂ’aparté.
Donc je vous disais plus haut : faites des composants et assemblez-les. Encapsulez-les même. Voici un exemple rapide :
Et là, je vois déjà les puristes qui s'affolent au fond. Du HTML dans le code. Oh My God.
J'avoue que la syntaxe peut paraître déroutante au début, mais si vous mettez ça de côté au début, vous y prendrez vite goût.
Par ailleurs, autant les premiers composants utilisaient du véritable HTML, autant le composite lui utilise des "balises" qui n'existent pas. C'est là la syntaxe de ReactJS : le JSX. Tout est balise et attribut. Ainsi vous vous y retrouverez beaucoup plus facilement dans votre code, croyez-moi. Ainsi, vous avez l'impression d'écrire du HTML, mais au final, React transforme tout ça pour pouvoir le manipuler de manière optimale. Même les H1/H2 du début ne seront pas rendus comme de vrais noeud HTML. Nous y reviendrons plus tard.
Bon vous allez me dire : "c'est bien beau tout ça, mais écrire tout ça pour faire une juste un Hello World statique c'est too much"
Et vous auriez raison.
React est très doué pour gérer les mises à jour de rendus. Donc autant lui passer des variables !
C'est là qu'intervient la notion de "props" (Rien à voir avec le Monsieur du presque même nom)
Les props, ce sont les properties que l'ont peut passer à un composant.
Ici, on passe donc l'attribut "name" au composant HelloWorld, avec la valeur "Dan". On récupère ainsi cette valeur dans le composant, via un accès par "this.props.name". Simple non ?
Si vous avez bien suivi la logique, vous aurez remarqué que le passage d'information ne se fait que dans un sens, du composant parent vers le composant enfant. JAMAIS dans l'autre sens. Les props sont ce que l'on appelle "immutable", en gros, en lecture seule.
Si vous souhaitez modifier une valeur au sein d'un composant, il faut faire appel au "state" de ce composant. Nous y reviendrons plus tard.
Maintenant que nous savons passer des paramètres à nos composants, cela implique que ces paramètres peuvent changer. Et s'ils changent, il faut remettre à jour votre vue. C'est là que la magie de React intervient : vos composants exécutent automatiquement la méthode render() à chaque fois qu'une de leur props est modifiée.
Et là, je revois les mêmes puristes du fond de la salle qui font de gros yeux.
Faire un render à chaque update, c'est écrouler les performances.
Et bien c'est vrai ! Profitons-en pour rappeler quelques best practices quand on parle du DOM :
Concrètement, faire un render() à chaque fois va à l'encontre de toutes ces best practices
Ok, donc, à ce moment là, vous vous dites que je vous vends un truc qui n'en vaut pas le coup. Restez assis, vous ne serez pas déçus ;)
React utilise et gère ce que l'on appelle un Virtual DOM. En fait, il s'agit d'un DOM allégé (pour être belle en maillot cet été) géré de manière transparente par React. C'est sur ce Virtual DOM que les opérations de render sont effectuées. Ainsi, React est en mesure de comparer efficacement l'ancienne et la nouvelle version, et ainsi déterminer les modifications à apporter au véritable DOM. Une fois ces modifications établies, il suffit de les appliquer en une fois au véritable DOM. On met donc à jour uniquement ce qui doit l'être. Un composant voit ses props modifiées ? Si son DOM n'est pas changé, il ne sera pas mis à jour sur votre page. Vous gagnez ainsi en performance.
Je vous avait dit que ça valait le coup de rester non ? ;)
Puisque l'on est dans l'optimisation, sachez que chaque composant React est soumis à un cycle de vie bien défini, dont voici les points clés :
Grâce à chacun de ces événements, vous pouvez donc interagir plus finement sur vos composants. Le point clé ici est le shouldComponentUpdate : il vous permettra de gagner énormément de performance en stoppant le rendu. Sachez que si vous bloquez le re-rendu d'un composant qui en comporte lui même d'autres, les composants enfants ne seront pas re-rendus également.
Enemy of the state
Vous vous souvenez, tout à l'heure, je vous parlais du "state" du composant, par opposition aux props. Le state est "mutable", ce qui veut dire que l'on peut le modifier, par opposition aux props, qui sont "immutable"
En gros, on peut dire qu'un composant parent peut modifier son state (suite à un clic par exemple) et que ce même state sera passé en props à son/ses enfant(s) Ainsi, le composant enfant recevra de nouvelles props au changement du state parent, et déclenchera (ou pas) un nouveau rendu.
Ce n'est pas clair ? Regardez-l'exemple ci dessous :)
Ici, on instancie un timer qui, toutes les secondes, va mettre à jour le state du composant. Le state est initialisé via la méthode getInitialState (ou alors dans un constructeur), et chaque tick met à jour le state. L'affichage est alors redessiné, vu que le Virtual DOM a changé.
C'est déjà plus clair non ?
Allez ça sera tout pour cette fois. La prochaine fois, nous verrons Redux, un des fidèles compagnons de ReactJS !
J'ai lus et relus l'article et il m'a vraiment plu car il est très intéressant!
Merci!