Oui, React prend en charge le développement front-end. La question est pourquoi.

Mise à jour: Cet article fait maintenant partie de mon livre «React.js Beyond The Basics». Lisez la version mise à jour de ce contenu et plus sur React sur jscomplete.com/react-beyond-basics .

Voici quelques raisons pour lesquelles React est devenu si rapidement populaire:

  • Travailler avec l'API DOM est difficile. React donne essentiellement aux développeurs la possibilité de travailler avec un navigateur virtuel plus convivial que le vrai navigateur. Le navigateur virtuel de React agit comme un agent entre le développeur et le navigateur réel.
  • React permet aux développeurs de décrire de manière déclarative leurs interfaces utilisateur et de modéliser l'état de ces interfaces. Cela signifie qu'au lieu de proposer des étapes pour décrire les transactions sur les interfaces, les développeurs décrivent simplement les interfaces en termes d'un état final (comme une fonction). Lorsque les transactions arrivent à cet état, React se charge de mettre à jour les interfaces utilisateur en fonction de cela.
  • React est juste du JavaScript, il y a une toute petite API à apprendre, juste quelques fonctions et comment les utiliser. Après cela, vos compétences en JavaScript font de vous un meilleur développeur React. Il n'y a pas de barrières à l'entrée. Un développeur JavaScript peut devenir un développeur React productif en quelques heures.

Mais il y a bien plus que cela. Essayons de couvrir toutes les raisons de la popularité croissante de React. Une des raisons est son DOM virtuel (algorithme de réconciliation de React). Nous allons travailler à travers un exemple pour montrer la valeur pratique réelle d'avoir un tel algorithme à votre disposition.

La définition officielle de React indique qu'il s'agit d'une bibliothèque JavaScript pour la création d'interfaces utilisateur . Il est important de comprendre les deux parties différentes de cette définition:

  1. React est une bibliothèque JavaScript . Ce n'est pas un cadre. Ce n'est pas une solution complète et nous aurons souvent besoin d'utiliser plus de bibliothèques avec React pour former n'importe quelle solution. React ne suppose rien sur les autres pièces dans une solution complète. Il se concentre sur une seule chose et sur le fait de très bien le faire.
  2. La chose que React fait vraiment bien est la deuxième partie de la définition: la création d'interfaces utilisateur . Une interface utilisateur est tout ce que nous mettons devant les utilisateurs pour qu'ils interagissent avec une machine. Les interfaces utilisateur sont partout, des simples boutons d'un micro-ondes au tableau de bord d'une navette spatiale. Si l'appareil que nous essayons d'interfacer peut comprendre JavaScript, nous pouvons utiliser React pour lui décrire une interface utilisateur.

Étant donné que les navigateurs Web comprennent JavaScript, nous pouvons utiliser React pour décrire les interfaces utilisateur Web. J'aime utiliser le mot décrire ici parce que c'est essentiellement ce que nous faisons avec React, nous lui disons simplement ce que nous voulons et React construira les interfaces utilisateur réelles, en notre nom, dans le navigateur Web. Sans React ou des bibliothèques similaires, nous aurions besoin de créer manuellement des interfaces utilisateur avec des API Web natives et JavaScript.

Lorsque vous entendez l'affirmation que «React est déclaratif», c'est exactement ce que cela signifie, nous décrivons les interfaces utilisateur avec React et lui disons ce que nous voulons (pas comment le faire). React s'occupera du «comment» et traduira nos descriptions déclaratives (que nous écrivons dans le langage React) en interfaces utilisateur réelles dans le navigateur. React partage ce simple pouvoir déclaratif avec HTML lui-même, mais avec React, nous arrivons à être déclaratifs pour les interfaces HTML qui représentent des données dynamiques, pas seulement des données statiques.

React a trois concepts de design principaux qui font sa popularité:

1 - L'utilisation de composants réutilisables, composables et avec état

Dans React, nous décrivons les interfaces utilisateur à l'aide de composants. Vous pouvez considérer les composants comme de simples fonctions (dans n'importe quel langage de programmation). Nous appelons des fonctions avec une entrée et elles nous donnent une sortie. Nous pouvons réutiliser des fonctions au besoin et composer des fonctions plus grandes à partir de fonctions plus petites.

Les composants sont exactement les mêmes; nous appelons leur entrée «propriétés» et «état», et une sortie de composant est une description d'une interface utilisateur (qui est similaire au HTML pour les navigateurs). Nous pouvons réutiliser un seul composant dans plusieurs interfaces utilisateur, et les composants peuvent contenir d'autres composants.

Cependant, contrairement aux fonctions pures, un composant React complet peut avoir un état privé pour contenir des données qui peuvent changer avec le temps.

2 - La nature des mises à jour réactives

Le nom de React est la simple explication de ce concept. Lorsque l'état d'un composant (l'entrée) change, l'interface utilisateur qu'il représente (la sortie) change également. Ce changement dans la description de l'interface utilisateur doit être reflété dans l'appareil avec lequel nous travaillons.

Dans un navigateur, nous devons régénérer les vues HTML dans le modèle d'objet de document (DOM). Avec React, nous n'avons pas à nous soucier de la façon de refléter ces changements, ni même de gérer quand apporter des modifications au navigateur; React réagira simplement aux changements d'état et mettra automatiquement à jour le DOM si nécessaire.

3 - La représentation virtuelle des vues en mémoire

Avec React, nous écrivons du HTML en utilisant JavaScript. Nous comptons sur la puissance de JavaScript pour générer du HTML qui dépend de certaines données, plutôt que sur l'amélioration du HTML pour le faire fonctionner avec ces données. L'amélioration du HTML est ce que font généralement les autres frameworks JavaScript. Par exemple, Angular étend le HTML avec des fonctionnalités telles que les boucles, les conditions et autres.

Lorsque nous ne recevons que les données du serveur (en arrière-plan, avec AJAX), nous avons besoin de quelque chose de plus que du HTML pour travailler avec ces données. Il utilise soit un HTML amélioré, soit la puissance de JavaScript lui-même pour générer le HTML. Les deux approches présentent des avantages et des inconvénients. React embrasse ce dernier, avec l'argument que les avantages sont plus forts que les inconvénients.

En fait, il existe un avantage majeur qui peut justifier à elle seule cette approche; l'utilisation de JavaScript pour rendre le HTML permet à React de conserver facilement une représentation virtuelle du HTML en mémoire (communément appelée le DOM virtuel ). React utilise le DOM virtuel pour rendre virtuellement un arbre HTML en premier, puis chaque fois qu'un état change et que nous obtenons un nouvel arbre HTML qui doit être transféré dans le DOM du navigateur, au lieu d'écrire le nouvel arbre entier, React écrira uniquement différence entre le nouvel arbre et l'arbre précédent (puisque React a les deux arbres en mémoire). Ce processus est connu sous le nom de Tree Reconciliation , et je pense que c'est la meilleure chose qui se soit produite dans le développement Web depuis AJAX!

Dans l'exemple suivant, nous allons nous concentrer sur ce dernier concept et voir un exemple pratique simple du processus de réconciliation des arbres et de la grande différence qu'il fait. Nous écrirons deux fois le même exemple HTML, d'abord en utilisant des API Web natives et du JavaScript vanilla, puis nous verrons comment décrire le même arbre HTML avec React.

Pour nous concentrer uniquement sur ce dernier concept, nous n'utiliserons pas de composants et nous simulerons une opération de changement d'état à l'aide d'une minuterie JavaScript. Nous n'allons pas non plus utiliser JSX, bien que l'utilisation de JSX rendra un code beaucoup plus simple. J'utilise JSX tout le temps lorsque j'écris React, mais travailler avec l'API React directement dans cet exemple vous permettra, espérons-le, de mieux comprendre ce concept.

Exemple d'algorithme de réconciliation de React

Pour suivre cet exemple, vous avez besoin d'un navigateur et d'un éditeur de code. Vous pouvez en fait utiliser un terrain de jeu de codage en ligne, mais je vais utiliser des fichiers locaux et les tester directement dans un navigateur (nous n'avons pas besoin d'un serveur Web):

Nous allons commencer cet exemple à partir de zéro. Créez un nouveau répertoire et lancez votre éditeur préféré ici:

mkdir react-democd react-demoatom .

Créez un index.htmlfichier dans ce répertoire et placez-y un modèle HTML standard. Incluez dans ce modèle un script.jsfichier et mettez une console.loginstruction dans ce script pour tester que l'inclusion fonctionne:

    React Demo     

Ouvrez le index.htmlfichier dans votre navigateur et assurez-vous que vous pouvez voir le modèle vide sans problème, et que vous pouvez voir dans l'onglet outils de développement de la console le console.logmessage de test que vous avez mis script.js:

open index.html # On Mac explorer index.html # On Windows

Now, let’s bring in the React library itself, which we can include from the Reactjs website. Copy both the react and react-dom scripts, and include them in index.html:

We’re including two different scripts here for an important reason: The React library itself can be used without a browser. To use React with a browser, we need the ReactDOM library.

When we refresh the browser now, we should see both React and ReactDOM available on the global scope:

With this simple setup, we can now access both React and ReactDOM APIs, and of course, we also have access to the native Web APIs and JavaScript which we are going to use first.

To insert HTML dynamically in the browser we can simply use pure JavaScript and the DOM Web API itself. Let’s create a div element to host our JavaScript HTML content and give it the id "js". In the body element of index.html, right before the script tag, add:

Now in script.js, let's grab this new div element by its id and put it in a constant. Let's name this constant jsContainer. We can use document.getElementById to grab the div from HTML:

jsContainer.innerHTML = ` Hello JS `;

To control the content of this div, we can use the innerHTML setter call on the div element directly. We can use this call to supply any HTML template that we want inserted in the DOM. Let's insert a div element with a class of "demo" and the string "Hello JS" as its content:

jsContainer.innerHTML = ` Hello JS `;ReactDOM.render( /* TODO: React's version of the HTML template */, reactContainer )

Make sure this works in the browser. You should see the “Hello JS” line on the screen now.

This demo div is our User Interface so far. It’s a very simple one. We just output a text for the user to see.

Both document.getElementById and element.innerHTML are actually part of the native DOM Web API. We are communicating with the browser directly here using the supported APIs of the Web platform. When we write React code, however, we use the React API instead, and we let React communicate with the browser using the DOM Web API.

React acts like our agent for the browser, and we mostly need to communicate with just React, our agent, and not the browser itself. I say mostly because there are cases where we still need to communicate with the browser, but those are rare.

To create the exact same User Interface that we have so far but with React API this time, let’s create another div element and give it an id of "react". In index.html, right under the div#js element, add:

Now, in script.js, create a new container constant for the new div:

const reactContainer = document.getElementById("react");

This container will be the only call we make to the native web API. ReactDOM needs this container to know where to host our application in the DOM.

With the react container identified, we can now use the ReactDOM library to render React's version of the HTML template to this container:

ReactDOM.render( /* TODO: React's version of the HTML template */, reactContainer )

What we’re going to do next is your first milestone in truly understanding the React library. Remember when I told you that with React we write HTML using JavaScript? This is exactly what we are going to do next.

To write our simple HTML User Interface, we are going to use JavaScript calls to React API, and by the end of the example you’ll have a better picture about the reason for doing so.

Instead of working with strings (as we did in the native JavaScript example above), in React, we work with objects. Any HTML string will be represented as an object using a React.createElement call (which is the core function in the React API).

Here’s the equivalent HTML User Interface we have so far with React:

ReactDOM.render( React.createElement( "div", { className: "demo" }, "Hello React" ), reactContainer );

React.createElement has many arguments:

  • The first argument is the HTML tag, which is div in our example.
  • The second argument is an object that represents any attributes we want this tag to have. To match the native JS example we used { className: "demo" } which translates to class="demo". Note how we used className instead of class in the attributes because with React it's all JavaScript that matches the Web API, not HTML itself.
  • The third argument is the content of the element. We’ve put a “Hello React” string in there.

We can test this now. The browser should render both “Hello JS” and “Hello React”. Let’s style the demo divs as a box, using this CSS, just so that we can visually split the screen. In index.html:

 .demo { border: 1px solid #ccc; margin: 1em; padding: 1em; } 

We now have two nodes, one being controlled with the DOM Web API directly, and another being controlled with the React API (which in turn uses the DOM Web API). The only major difference between the ways we are building these two nodes in the browser is that in the JS version we used a string to represent the content, while in the React version we used pure JavaScript calls and represented the content with an object instead of a string.

No matter how complicated the HTML User Interface is going to get, when using React, every HTML element will be represented with a JavaScript object using a React.createElement call.

Let’s now add some more features to our simple User Interface. Let’s add a text box to read input from the user.

To nest elements in our HTML template, it’s straight forward in the JS version because it’s just HTML. For example, to make the demo div render an element, we simply add it to the content:

jsContainer.innerHTML = ` Hello JS `;

We can do the same with React by adding more arguments after the 3rd argument for React.createElement. To match what we did in the native JS example, we can add a 4th argument that is another React.createElement call that renders an input element (remember, every HTML element is an object):

ReactDOM.render( React.createElement( "div", { className: "demo" }, "Hello React", React.createElement("input") ), reactContainer );

At this point, if you’re questioning what we’re doing and thinking “this is complicating a simple process”, you are totally right! But there is a very good reason for what we’re doing. Keep reading.

Let’s also render a timestamp in both versions. In the JS version, let’s put the timestamp in a paragraph element. We can use a call to new Date() to display a simple timestamp:

jsContainer.innerHTML = ` Hello JS  

${new Date()}

`;

To do the same in React, we add a 5th argument to the top-level div element. This new 5th argument is another React.createElement call, this time using a p tag, with no attributes, and the new Date() string for content:

ReactDOM.render( React.createElement( "div", { className: "demo" }, "Hello React", React.createElement("input"), React.createElement( "p", null, new Date().toString() ) ), reactContainer );

Both JS and React versions are still rendering the exact same HTML in the browser.

As you can see, so far, using React is actually a lot harder than the simple and familiar native way. What is it that React does so well that’s worth giving up the familiar HTML and having to learn a new API to write what can be simply written in HTML? The answer is not about rendering the first HTML view, it’s about what we need to do to update any existing view in the DOM.

So, let’s do an update operation on the DOM we have so far. Let’s simply make the timestamp tick every second.

We can easily repeat a JavaScript function call in a browser using the setInterval Web timer API. So, let's put all of our DOM manipulations for both JS and React versions in a function, call it render, and use it in a setInterval call to make it repeat every second.

Here’s the full final code in script.js:

const jsContainer = document.getElementById("js"); const reactContainer = document.getElementById("react"); const render = () => { jsContainer.innerHTML = ` Hello JS  

${new Date()}

`; ReactDOM.render( React.createElement( "div", { className: "demo" }, "Hello React ", React.createElement("input"), React.createElement( "p", null, new Date().toString() ) ), reactContainer ); } setInterval(render, 1000);

When we refresh the browser now, the timestamp string should be ticking every second in both versions. We are now updating our User Interface in the DOM.

This is the moment when React will potentially blow your mind. If you try to type something in the text box of the JS version, you won’t be able to. This is very much expected because we’re basically throwing away the whole DOM node on every tick and regenerating it. However, if you try to type something in the text box that’s rendered with React, you can certainly do so!

Although the whole React rendering code is within our ticking timer, React is changing only the timestamp paragraph and not the whole DOM node. This is why the text input box was not regenerated and we were able to type in it.

You can see the different ways we’re updating the DOM visually if you inspect the two DOM nodes in a Chrome dev tools elements panel. The Chrome div tools highlights any HTML elements that get updated. You’ll see how we are regenerating the whole “js” div on every tick, while React is smartly only regenerating the paragraph with the timestamp string.

React has a smart diffing algorithm that it uses to only regenerate in its DOM node what actually needs to be regenerated while it keeps everything else as is. This diffing process is possible because of React’s virtual DOM and the fact that we have a representation of our User Interface in memory (because we wrote in JavaScript).

Using the virtual DOM, React keeps the last DOM version in memory and when it has a new DOM version to take to the browser, that new DOM version will also be in memory, so React can compute the difference between the new and the old versions (in our case, the difference is the timestamp paragraph).

React will then instruct the browser to update only the computed diff and not the whole DOM node. No matter how many times we regenerate our interface, React will take to the browser only the new “partial” updates.

Not only is this method a lot more efficient, but it also removes a big layer of complexity for the way we think about updating User Interfaces. Having React do all the computations about whether we should update the DOM or not enables us to focus on thinking about our data (state) and the way to describe a User Interface for it.

We then manage the updates on our data as needed without worrying about the steps needed to reflect these updates on the actual User Interface in the browser (because we know React will do exactly that and it will do that in an efficient way!)

Thanks for reading! You can view the source code of my demo here, and you can see the demo running here.

Learning React or Node? Checkout my books:

  • Learn React.js by Building Games
  • Node.js Beyond the Basics