Pourquoi JavaScript dévore le HTML: exemples de code

Le développement Web est en constante évolution. Récemment, une tendance est devenue populaire, ce qui contredit fondamentalement l'idée généralement acceptée de la façon de développer des applications Web. Certains ont de grands espoirs pour lui, tandis que d'autres sont déçus. Chacun a ses propres raisons, ce qui en un mot est difficile à expliquer.



Le code de page Web se compose traditionnellement de trois sections, chacune remplissant ses fonctions: le code HTML définit la structure et la sémantique, le code CSS détermine l'apparence et le code JavaScript détermine son comportement. Dans les équipes impliquant des concepteurs, des développeurs HTML / CSS et des développeurs JavaScript, cette séparation est naturelle: les concepteurs définissent des éléments visuels et une interface utilisateur, les développeurs HTML et CSS placent ces éléments visuels sur une page dans un navigateur, et les développeurs JavaScript ajoutent une interaction utilisateur à liez tout ensemble et «faites-le fonctionner». Chacun peut travailler sur ses tùches sans s'immiscer dans le code des deux autres catégories de développeurs. Mais tout cela est vrai pour le soi-disant «ancien style».

Ces derniĂšres annĂ©es, les dĂ©veloppeurs JavaScript ont commencĂ© Ă  dĂ©terminer la structure de la page en JavaScript et non en HTML (par exemple, en utilisant le framework React js ), ce qui contribue Ă  simplifier la crĂ©ation et la maintenance du code d'interaction utilisateur. Sans cadres js, dĂ©velopper des sites Web modernes est beaucoup plus difficile. Bien sĂ»r, lorsque vous dites Ă  quelqu'un que le code HTML Ă©crit par lui doit ĂȘtre divisĂ© en morceaux et mĂ©langĂ© avec JavaScript, qu'il connaĂźt trĂšs bien, cela (pour des raisons Ă©videntes) peut ĂȘtre perçu avec hostilitĂ©. Au minimum, l'interlocuteur demandera pourquoi nous en avons besoin et comment nous en bĂ©nĂ©ficierons.

En tant que dĂ©veloppeur JavaScript dans une Ă©quipe interfonctionnelle, cette question me est parfois posĂ©e, et il m'est souvent difficile d'y rĂ©pondre. Tous les documents que j'ai trouvĂ©s sur ce sujet sont Ă©crits pour un public qui connaĂźt dĂ©jĂ  JavaScript. Et ce n'est pas trĂšs bon pour ceux qui se spĂ©cialisent exclusivement en HTML et CSS. Mais le modĂšle HTML-in-JS (ou quelque chose d'autre qui offre les mĂȘmes avantages) est susceptible d'ĂȘtre demandĂ© pendant un certain temps, donc je pense que c'est une chose importante que toutes les personnes impliquĂ©es dans le dĂ©veloppement Web devraient comprendre.

Dans cet article, je donnerai des exemples de code pour ceux qui sont intĂ©ressĂ©s, mais mon objectif est d'expliquer cette approche afin qu'elle puisse ĂȘtre comprise sans eux.

Likbez: HTML, CSS et JavaScript


Pour maximiser l'audience de cet article, je veux parler briÚvement du rÎle que jouent ces langues dans la création de pages Web et du type de séparation qui existait initialement entre elles. Si vous le savez tous, vous pouvez ignorer cette section.

HTML: pour la structure et la sémantique


Le code HTML (HyperText Markup Language) dĂ©finit la structure et la sĂ©mantique du contenu qui sera placĂ© sur la page. Par exemple, le code HTML de cet article contient le texte que vous lisez maintenant et conformĂ©ment Ă  la structure spĂ©cifiĂ©e, ce texte est placĂ© dans un paragraphe distinct, aprĂšs l'en-tĂȘte et avant de coller CodePen .

Par exemple, créez une page Web simple avec une liste de courses:



Nous pouvons enregistrer ce code dans un fichier, l'ouvrir dans un navigateur Web et le navigateur affichera le rĂ©sultat. Comme vous pouvez le voir, le code HTML dans cet exemple est une page qui contient l'en-tĂȘte "Liste d'achats" (2 articles), une zone de texte de saisie, un bouton "Ajouter un article" et une liste de deux articles ("Oeufs" et «PĂ©trole»). L'utilisateur saisira l'adresse dans son navigateur Web, puis le navigateur demandera ce code HTML au serveur, le tĂ©lĂ©chargera et l'affichera. S'il y a dĂ©jĂ  des Ă©lĂ©ments dans la liste, le serveur peut envoyer du HTML avec des Ă©lĂ©ments prĂȘts Ă  l'emploi, comme dans cet exemple.

Essayez de taper quelque chose dans le champ de saisie et cliquez sur le bouton "Ajouter un Ă©lĂ©ment". Vous verrez que rien ne se passe. Le bouton n'est associĂ© Ă  aucun code susceptible de modifier HTML, et HTML ne peut rien changer par lui-mĂȘme. Nous y reviendrons dans une minute.

CSS: pour changer le look


Le code CSS (feuilles de style en cascade) définit l'apparence de la page. Par exemple, le CSS de cet article définit la police, l'espacement et la couleur du texte que vous lisez.

Vous avez peut-ĂȘtre remarquĂ© que notre exemple de liste de courses semble trĂšs simple. HTML ne permet pas de spĂ©cifier des Ă©lĂ©ments comme l'espacement, la taille des polices et les couleurs. C'est pourquoi nous utilisons CSS. Nous pourrions ajouter du code CSS pour cette page pour la dĂ©corer un peu:



Comme vous pouvez le voir, ce code CSS a changĂ© la taille et l'Ă©paisseur des caractĂšres du texte, ainsi que la couleur d'arriĂšre-plan. Un dĂ©veloppeur peut, par analogie, Ă©crire des rĂšgles pour son propre style, et elles seront appliquĂ©es sĂ©quentiellement Ă  toute structure HTML: si nous ajoutons des Ă©lĂ©ments section, bouton ou ul Ă  cette page , les mĂȘmes changements de police s'appliqueront.
Mais le bouton Ajouter un élément ne fait toujours rien: ici, nous avons juste besoin de JavaScript.

JavaScript: pour implémenter le comportement


Le code JavaScript définit le comportement des éléments interactifs ou dynamiques d'une page. Par exemple, CodePen est écrit en utilisant JavaScript.

Pour que le bouton Ajouter un Ă©lĂ©ment dans notre exemple fonctionne sans JavaScript, nous devons utiliser un code HTML spĂ©cial pour le forcer Ă  renvoyer des donnĂ©es au serveur ( <form action \ u003d '...'> si vous ĂȘtes soudain intĂ©ressĂ©). De plus, le navigateur rechargera la version mise Ă  jour de l'intĂ©gralitĂ© du fichier HTML sans enregistrer l'Ă©tat actuel de la page. Si cette liste de courses faisait partie d'une grande page Web, tout ce que l'utilisateur faisait serait perdu. Peu importe le nombre de pixels que vous avez dĂ©placĂ©s vers le bas lors de la lecture du texte - lorsque vous redĂ©marrez le serveur vous ramĂšnera au dĂ©but, peu importe le nombre de minutes de la vidĂ©o que vous avez regardĂ©e - lorsque vous redĂ©marrez, elle recommencera.

C'est ainsi que fonctionnaient toutes les applications Web: chaque fois qu'un utilisateur interagissait avec une page Web, il semblait fermer son navigateur Web et l'ouvrir Ă  nouveau. Cela n'a pas beaucoup d'importance pour une simple Ă©tude de cas, mais pour une grande page complexe, qui peut prendre un certain temps Ă  charger, cette approche n'est efficace ni pour le navigateur ni pour le serveur.

Si nous voulons changer quelque chose sur la page sans recharger complĂštement cette page, nous devons utiliser JavaScript:



Maintenant, lorsque nous tapons le texte dans le champ de saisie et cliquez sur le bouton Ajouter un élément, notre nouvel élément est ajouté à la liste et le nombre d'éléments en haut est mis à jour! Dans une application réelle, nous ajouterions également du code pour envoyer un nouvel élément au serveur en arriÚre-plan afin qu'il apparaisse lors du prochain chargement de la page.

La sĂ©paration de JavaScript de HTML et CSS est justifiĂ©e mĂȘme dans cet exemple simple. Des interactions plus complexes fonctionnent comme ceci: le HTML est chargĂ© et affichĂ©, et JavaScript est ensuite lancĂ© pour y ajouter quelque chose et le changer. Cependant, Ă  mesure que la complexitĂ© de l'application Web augmente, nous devons surveiller attentivement quoi, oĂč et quand notre code JavaScript change.

Si nous continuions à développer cette application de liste d'achats, nous pourrions ajouter des boutons pour modifier ou supprimer des articles de la liste. Supposons que nous écrivions du code JavaScript pour un bouton qui supprime un élément, mais oublions d'ajouter du code qui met à jour les informations sur le nombre total d'éléments en haut de la page. Soudain, nous obtenons une erreur: aprÚs que l'utilisateur a supprimé l'élément, le nombre total indiqué sur la page ne correspondra pas à la liste!

DĂšs que nous avons remarquĂ© l'erreur, nous l'avons corrigĂ©e en ajoutant la mĂȘme ligne totalText.innerHTML de notre code pour ajouter un Ă©lĂ©ment au code pour supprimer un Ă©lĂ©ment. Maintenant, nous avons le mĂȘme code, qui est dupliquĂ© Ă  plusieurs endroits. Plus tard, disons, nous voulons changer ce code afin qu'au lieu de «(2 Ă©lĂ©ments)» en haut de la page, il affiche «ÉlĂ©ments: 2». Nous devons nous assurer de ne pas oublier de mettre Ă  jour ce code aux trois endroits: en HTML, dans le code JavaScript pour le bouton Ajouter un Ă©lĂ©ment et dans le code JavaScript pour le bouton Supprimer un Ă©lĂ©ment. Si nous ne le faisons pas, nous aurons une autre erreur, Ă  cause de laquelle ce texte changera considĂ©rablement aprĂšs avoir interagi avec l'utilisateur.

DĂ©jĂ  dans cet exemple simple, nous voyons combien il est facile de se confondre dans le code. Bien sĂ»r. Il existe des approches et des pratiques pour rationaliser le code JavaScript afin de faciliter la rĂ©solution de ce problĂšme. Cependant, Ă  mesure que les choses se compliquent, nous devrons poursuivre la restructuration et constamment rĂ©Ă©crire le projet afin qu'il puisse ĂȘtre facilement dĂ©veloppĂ© et maintenu. Bien que HTML et JavaScript soient stockĂ©s sĂ©parĂ©ment, cela peut prendre beaucoup d'efforts pour assurer la synchronisation entre les deux. C'est l'une des raisons pour lesquelles les nouveaux frameworks JavaScript tels que React sont devenus populaires: ils sont conçus pour fournir une relation plus formalisĂ©e et efficace entre HTML et JavaScript. Pour comprendre comment cela fonctionne, nous devons d'abord aller un peu plus loin dans l'informatique.

Programmation impérative vs déclarative


La chose clé à comprendre est la différence de pensée. La plupart des langages de programmation vous permettent de suivre un seul paradigme, bien que certains d'entre eux prennent en charge deux à la fois. Il est important de comprendre les deux paradigmes afin d'apprécier le principal avantage de HTML-in-JS du point de vue du développeur JavaScript.

  • . «» , . ( ) : , , . , , . - «». Vanilla JavaScript , jQuery. JavaScript .
    • « X, Y, Z».
    • : , .selected; , .selected.

  • . , . , , «» (), , - . , . (, React), , , . , , , , . , :
    • « XYZ. , , .
    • Exemple: cet Ă©lĂ©ment a une classe .selected si l'utilisateur l'a sĂ©lectionnĂ©.


HTML est un langage déclaratif


Oubliez JavaScript pendant un moment. Voici un fait important: HTML est un langage déclaratif. Dans le fichier HTML, vous pouvez déclarer quelque chose comme:

<section>
  <h1>Hello</h1>
  <p>My name is Mike.</p>
</section>

Lorsque le navigateur Web lit ce code HTML, il détermine indépendamment les étapes nécessaires et les exécute:

  1. Créez un élément de section .
  2. CrĂ©ez un Ă©lĂ©ment d'en-tĂȘte de niveau 1 ( h1 ).
  3. Définissez le texte de l'élément de titre sur «Bonjour».
  4. Placez l'élément title dans l'élément section.
  5. Créez un élément de paragraphe ( p ).
  6. Définissez le texte de l'élément de paragraphe sur "Mon nom est Mike".
  7. Placez un élément de paragraphe dans un élément de section .
  8. Placez l'élément de section dans un document HTML.
  9. Affichez le document Ă  l'Ă©cran.

Pour un développeur Web, la façon dont le navigateur fait ces choses n'a pas d'importance: tout ce qui compte, c'est ce qu'il fait. Ceci est un excellent exemple pour illustrer la différence entre les deux paradigmes de programmation. En bref, HTML est une abstraction déclarative enroulée autour d'un moteur de rendu de navigateur Web implémenté de maniÚre impérative. Il se soucie de la façon dont vous n'avez qu'à vous soucier de quoi. Vous pouvez profiter de la vie en écrivant du HTML déclaratif parce que les bonnes personnes de Mozilla, Google et Apple ont écrit un code impératif pour vous lors de la création de votre navigateur Web.

JavaScript est un langage impératif


Nous avons déjà examiné un exemple simple de JavaScript impératif dans l'exemple de liste d'achats ci-dessus, et j'ai décrit comment la complexité des fonctions d'application affecte l'effort requis pour les implémenter et la probabilité d'erreurs dans cette implémentation.

Examinons maintenant une tĂąche lĂ©gĂšrement plus complexe et voyons comment elle peut ĂȘtre simplifiĂ©e Ă  l'aide d'une approche dĂ©clarative. Imaginez une page Web contenant les Ă©lĂ©ments suivants:

  • une liste de drapeaux marquĂ©s, dont chaque ligne change de couleur lorsqu'elle est sĂ©lectionnĂ©e;
  • le texte ci-dessous, par exemple, «1 sur 4 sĂ©lectionné», qui doit ĂȘtre mis Ă  jour lorsque les indicateurs sont modifiĂ©s;
  • Bouton SĂ©lectionner tout, qui doit ĂȘtre dĂ©sactivĂ© si toutes les cases Ă  cocher sont dĂ©jĂ  sĂ©lectionnĂ©es;
  • SĂ©lectionnez le bouton Aucun, qui doit ĂȘtre dĂ©sactivĂ© si les cases Ă  cocher ne sont pas sĂ©lectionnĂ©es.

Voici une implémentation en HTML simple, CSS et JavaScript impératif:



const captionText = document.getElementById('caption-text');
const checkAllButton = document.getElementById('check-all-button');
const uncheckAllButton = document.getElementById('uncheck-all-button');
const checkboxes = document.querySelectorAll('input[type="checkbox"]');

function updateSummary() {
  let numChecked = 0;
  checkboxes.forEach(function(checkbox) {
    if (checkbox.checked) {
      numChecked++;
    }
  });
  captionText.innerHTML = `${numChecked} of ${checkboxes.length} checked`;
  if (numChecked === 0) {
    checkAllButton.disabled = false;
    uncheckAllButton.disabled = true;
  } else {
    uncheckAllButton.disabled = false;
  }
  if (numChecked === checkboxes.length) {
    checkAllButton.disabled = true;
  }
}

checkAllButton.addEventListener('click', function() {
  checkboxes.forEach(function(checkbox) {
    checkbox.checked = true;
    checkbox.closest('tr').className = 'checked';
  });
  updateSummary();
});

uncheckAllButton.addEventListener('click', function() {
  checkboxes.forEach(function(checkbox) {
    checkbox.checked = false;
    checkbox.closest('tr').className = '';
  });
  updateSummary();
});

checkboxes.forEach(function(checkbox) {
  checkbox.addEventListener('change', function(event) {
    checkbox.closest('tr').className = checkbox.checked ? 'checked' : '';
    updateSummary();
  });
});

Mal de tĂȘte tel quel


Pour implémenter cette fonction en utilisant impérativement JavaScript, nous devons donner au navigateur des instructions détaillées. Il s'agit d'une description verbale du code de l'exemple ci-dessus.
Dans notre HTML, nous déclarons la structure de page d'origine:
  • Il y a quatre Ă©lĂ©ments de ligne (une ligne d'un tableau, c'est une liste), chacun contenant un indicateur. Le troisiĂšme drapeau est vĂ©rifiĂ©.
  • Il y a un texte «1 sur 4 sĂ©lectionné».
  • Un bouton SĂ©lectionner tout est activĂ©.
  • Il y a un bouton Ne rien sĂ©lectionner, qui est dĂ©sactivĂ©.

Dans notre JavaScript, nous Ă©crivons des instructions sur ce qui doit ĂȘtre changĂ© lorsque chacun de ces Ă©vĂ©nements se produit:
Lorsqu'un indicateur passe de non marqué à marqué:
  • Recherchez la ligne contenant la case Ă  cocher et ajoutez-y la classe CSS .selected.
  • Trouvez tous les drapeaux dans la liste et calculez combien d'entre eux sont marquĂ©s et combien ne le sont pas.
  • Recherchez le texte et mettez-le Ă  jour en indiquant le nombre correct d'achats sĂ©lectionnĂ©s et leur nombre total.
  • Recherchez le bouton Ne rien sĂ©lectionner et activez-le s'il a Ă©tĂ© dĂ©sactivĂ©.
  • Si toutes les cases Ă  cocher sont maintenant cochĂ©es, recherchez le bouton SĂ©lectionner tout et dĂ©sactivez-le.

Lorsqu'un indicateur passe de marqué à non marqué:
  • Recherchez la ligne contenant l'indicateur et supprimez-en la classe .selected.
  • Trouvez toutes les cases Ă  cocher dans la liste et calculez combien d'entre elles sont cochĂ©es et combien ne le sont pas.
  • Trouvez l'Ă©lĂ©ment de texte de CV et mettez-le Ă  jour avec le nombre et le total vĂ©rifiĂ©s.
  • Recherchez le bouton SĂ©lectionner tout et activez-le s'il a Ă©tĂ© dĂ©sactivĂ©.
  • Si toutes les cases ne sont pas cochĂ©es, recherchez le bouton Ne rien sĂ©lectionner et dĂ©sactivez-le.

Lorsque le bouton Sélectionner tout est enfoncé:
  • Trouvez toutes les cases Ă  cocher dans la liste et marquez-les.
  • Recherchez toutes les lignes de la liste et ajoutez-leur la classe .selected.
  • Trouvez le texte et mettez-le Ă  jour.
  • Recherchez le bouton SĂ©lectionner tout et dĂ©sactivez-le.
  • Recherchez le bouton Ne rien sĂ©lectionner et activez-le.

Lorsque vous appuyez sur le bouton Ne rien sélectionner:
  • Recherchez toutes les cases Ă  cocher dans la liste et dĂ©cochez toutes les cases.
  • Recherchez toutes les lignes de la liste et supprimez-en la classe .selected.
  • Recherchez l'Ă©lĂ©ment de texte de reprise et mettez-le Ă  jour.
  • Recherchez le bouton SĂ©lectionner tout et activez-le.
  • Recherchez le bouton Ne rien sĂ©lectionner et dĂ©sactivez-le.

Wow ... C'est beaucoup, non? Eh bien, il vaut mieux ne pas oublier d'écrire du code pour toutes les situations possibles. Si nous oublions ou gùchons l'une de ces instructions, nous obtenons une erreur: les totaux ne correspondent pas aux cases à cocher, ou le bouton qui ne fait rien lorsque vous cliquez dessus, ou la ligne sélectionnée a la mauvaise couleur ou quelque chose, est activé pourtant, ce à quoi nous n'avons pas pensé et ne saurons pas tant que l'utilisateur ne se plaindra pas.

Nous avons vraiment un gros problĂšme ici: il n'y a pas d'entitĂ© qui contiendrait des informations complĂštes sur l' Ă©tatde notre application (dans ce cas, c'est la rĂ©ponse Ă  la question «quels drapeaux sont marquĂ©s?») et serait responsable de la mise Ă  jour de ces informations. Les indicateurs, bien sĂ»r, savent s'ils sont vĂ©rifiĂ©s, mais le code CSS des lignes du tableau, du texte et de chaque bouton doit Ă©galement en ĂȘtre conscient. Cinq copies de ces informations sont stockĂ©es sĂ©parĂ©ment dans le code HTML, et lorsqu'elles changent dans l'un de ces endroits, le dĂ©veloppeur JavaScript doit les capturer et Ă©crire un code impĂ©ratif pour se synchroniser avec les changements dans d'autres endroits.

Et ceci est toujours un exemple simple d'un petit composant de page. MĂȘme si cet ensemble d'instructions ressemble Ă  un mal de tĂȘte, imaginez la complexitĂ© et la fragilitĂ© d'une application Web plus grande lorsque vous devez implĂ©menter tout cela en JavaScript impĂ©ratif. Pour de nombreuses applications Web complexes et modernes, cette solution n'est pas mise Ă  l'Ă©chelle Ă  partir du mot «complĂštement».

Nous recherchons la source de la vérité


Des outils comme React permettent une utilisation déclarative de JavaScript. Tout comme HTML est une abstraction déclarative sur les instructions d'affichage dans un navigateur Web, React est une abstraction déclarative sur JavaScript.

Rappelez-vous comment HTML nous permet de nous concentrer sur la structure de la page plutĂŽt que sur les dĂ©tails d'implĂ©mentation, et comment le navigateur affiche-t-il cette structure? De mĂȘme, lorsque nous utilisons React, nous pouvons nous concentrer sur la structure, la dĂ©finir en fonction des donnĂ©es stockĂ©es en un seul endroit. Ce processus est appelĂ© liaison unidirectionnelle et l'emplacement des donnĂ©es d'Ă©tat de l'application est appelĂ© «source unique de vĂ©rité». Lorsque la source de la vĂ©ritĂ© change, React mettra automatiquement Ă  jour la structure de la page pour nous. Il s'occupera des Ă©tapes nĂ©cessaires dans les coulisses, comme le fait un navigateur Web pour HTML. Bien que React soit utilisĂ© Ă  titre d'exemple ici, cette approche fonctionne Ă©galement pour d'autres cadres tels que Vue.

Revenons à notre liste de cases à cocher de l'exemple ci-dessus. Dans ce cas, la «vérité» que nous voulons savoir est assez concise: quels drapeaux sont vérifiés? D'autres détails (par exemple, le texte, la couleur des lignes, les boutons activés) sont déjà des informations obtenues sur la base de la source de la vérité. Et pourquoi devraient-ils avoir leur propre copie de ces informations? Ils doivent simplement utiliser une seule source de vérité en lecture seule, et tous les éléments de la page doivent «simplement savoir» quelles cases sont cochées et se comporter en conséquence. Vous pouvez dire que les lignes, le texte et les boutons du tableau devraient pouvoir répondre automatiquement à une case à cocher selon qu'elle est cochée ou non («voir ce qui s'y passe?»)

Dis-moi ce que tu veux (ce que tu veux vraiment)


Pour implémenter cette page avec React, nous pouvons remplacer la liste par quelques descriptions de faits simples:

  • Il existe une liste de valeurs vraies / fausses appelĂ©es checkboxValues ​​qui montre quels champs sont marquĂ©s.
    • Exemple: checkboxValues ​​\ u003d [faux, faux, vrai, faux]
    • Cette liste montre que nous avons quatre drapeaux, seul le troisiĂšme est dĂ©fini.

  • Pour chaque valeur de checkboxValues ​​dans le tableau, il y a une ligne qui:
    • a une classe CSS appelĂ©e .selected si la valeur est vraie, et
    • contient un indicateur qui est vĂ©rifiĂ© si la valeur est vraie.

  • Il existe un Ă©lĂ©ment de texte qui contient le texte "{x} de {y} sĂ©lectionnĂ©", oĂč {x} est le nombre de vraies valeurs dans checkboxValues ​​et {y} est le nombre total de valeurs dans checkboxValues.
  • Il existe un bouton SĂ©lectionner tout qui est activĂ© si checkboxValues ​​a de fausses valeurs.
  • Select None, , checkboxValues ​​ true.
  • , checkboxValues.
  • Select All , checkboxValues ​​ true.
  • Select None checkboxValues ​​ false.

Vous remarquerez que les trois derniers paragraphes sont toujours des instructions impératives («Lorsque cela se produit, faites-le»), mais c'est le seul code impératif que nous devons écrire. Ce sont trois lignes de code, et elles mettent toutes à jour une seule source de vérité.

Le reste est constituĂ© d'instructions dĂ©claratives («il y a ...»), qui sont dĂ©sormais intĂ©grĂ©es directement dans la dĂ©finition de la structure de la page. Pour ce faire, nous Ă©crivons du code pour nos Ă©lĂ©ments Ă  l'aide d'une extension de syntaxe JavaScript spĂ©ciale - JavaScript XML (JSX). Il ressemble au HTML: JSX vous permet d'utiliser une syntaxe de type HTML pour dĂ©crire la structure de l'interface, ainsi que du JavaScript standard. Cela nous permet de mĂ©langer la logique JS avec la structure HTML, de sorte que la structure peut ĂȘtre diffĂ©rente Ă  tout moment. Tout dĂ©pend du contenu de checkboxValues.

Nous réécrivons notre exemple sur React:



function ChecklistTable({ columns, rows, initialValues, ...otherProps }) {
  const [checkboxValues, setCheckboxValues] = React.useState(initialValues);
  
  function checkAllBoxes() {
    setCheckboxValues(new Array(rows.length).fill(true));
  }
  
  function uncheckAllBoxes() {
    setCheckboxValues(new Array(rows.length).fill(false));
  }
  
  function setCheckboxValue(rowIndex, checked) {
    const newValues = checkboxValues.slice();
    newValues[rowIndex] = checked;
    setCheckboxValues(newValues);
  }
  
  const numItems = checkboxValues.length;
  const numChecked = checkboxValues.filter(Boolean).length;
  
  return (
    <table className="pf-c-table pf-m-grid-lg" role="grid" {...otherProps}>
      <caption>
        <span>{numChecked} of {numItems} items checked</span>
        <button
          onClick={checkAllBoxes}
          disabled={numChecked === numItems}
          className="pf-c-button pf-m-primary"
          type="button"
        >
          Check all
        </button>
        <button
          onClick={uncheckAllBoxes}
          disabled={numChecked === 0}
          className="pf-c-button pf-m-secondary"
          type="button"
        >
          Uncheck all
        </button>
      </caption>
      <thead>
        <tr>
          <td />
          {columns.map(function(column) {
            return <th scope="col" key={column}>{column}</th>;
          })}
        </tr>
      </thead>
      <tbody>
        {rows.map(function(row, rowIndex) {
          const [firstCell, ...otherCells] = row;
          const labelId = `item-${rowIndex}-${firstCell}`;
          const isChecked = checkboxValues[rowIndex];
          return (
            <tr key={firstCell} className={isChecked ? 'checked' : ''}>
              <td className="pf-c-table__check">
                <input
                  type="checkbox"
                  name={firstCell}
                  aria-labelledby={labelId}
                  checked={isChecked}
                  onChange={function(event) {
                    setCheckboxValue(rowIndex, event.target.checked);
                  }}
                />
              </td>
              <th data-label={columns[0]}>
                <div id={labelId}>{firstCell}</div>
              </th>
              {otherCells.map(function(cell, cellIndex) {
                return (
                  <td key={cell} data-label={columns[1 + cellIndex]}>
                    {cell}
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
};

function ShoppingList() {
  return (
    <ChecklistTable
      aria-label="Shopping list"
      columns={['Item', 'Quantity']}
      rows={[
        ['Sugar', '1 cup'],
        ['Butter', 'œ cup'],
        ['Eggs', '2'],
        ['Milk', 'œ cup'],
      ]}
      initialValues={[false, false, true, false]}
    />
  );
}

ReactDOM.render(
  <ShoppingList />,
  document.getElementById('shopping-list')
);


JSX a l'air particulier. Lorsque j'ai rencontrĂ© cela pour la premiĂšre fois, il m'a semblĂ© qu'il Ă©tait tout simplement impossible de le faire. Ma premiĂšre rĂ©action a Ă©tĂ©: «Quoi? Le HTML ne peut pas ĂȘtre dans le code JavaScript! " Et je n'Ă©tais pas le seul. Cependant, ce n'est pas du HTML, mais du JavaScript habillĂ© en HTML. En fait, c'est une solution puissante.

Rappelez-vous ces 20 instructions impĂ©ratives ci-dessus? Nous en avons maintenant trois. Les autres instructions impĂ©ratives (internes) que React exĂ©cute pour nous dans les coulisses - Ă  chaque fois que checkboxValues ​​change.

Avec ce code, une situation ne peut plus se produire lorsque le texte ou la couleur de la ligne ne correspond pas aux cases Ă  cocher, ou lorsque le bouton est activĂ©, bien qu'il doive ĂȘtre dĂ©sactivĂ©. Il existe toute une catĂ©gorie d'erreurs qui ne peuvent tout simplement plus se produire dans notre application Web. Tout le travail est effectuĂ© sur la base d'une seule source de vĂ©ritĂ©, et nous, dĂ©veloppeurs, pouvons Ă©crire moins de code et mieux dormir la nuit. Eh bien, les dĂ©veloppeurs JavaScript, au moins ...

JavaScript a vaincu HTML: affamé


À mesure que les applications Web deviennent plus complexes, le maintien de la sĂ©paration classique des tĂąches entre HTML et JavaScript devient de plus en plus pĂ©nible. HTML a Ă©tĂ© initialement conçu pour les pages Web statiques. Pour y ajouter des fonctions interactives plus complexes, il est nĂ©cessaire d'implĂ©menter la logique appropriĂ©e en JavaScript impĂ©ratif, qui avec chaque ligne de code devient de plus en plus confus et fragile.

Avantages de l'approche moderne: prévisibilité, réutilisabilité et combinaison


La possibilitĂ© d'utiliser une seule source de vĂ©ritĂ© est l'avantage le plus important de ce modĂšle, mais il prĂ©sente d'autres avantages. La dĂ©finition de nos Ă©lĂ©ments de page dans le code JavaScript signifie que nous pouvons rĂ©utiliser des composants (blocs individuels d'une page Web), nous empĂȘchant de copier et de coller le mĂȘme code HTML Ă  plusieurs endroits. Si nous devons changer un composant, changez simplement son code en un seul endroit. Dans ce cas, des modifications se produiront dans toutes les copies du composant (Ă  l'intĂ©rieur d'une ou mĂȘme dans de nombreuses applications Web, si nous utilisons des composants rĂ©utilisables).

Nous pouvons prendre des composants simples et les assembler comme des cubes LEGO, créant des composants plus complexes et utiles sans rendre leur logique trop confuse. Et si nous utilisons des composants créés par d'autres développeurs, nous pouvons facilement reporter des mises à jour ou des corrections de bogues sans avoir à réécrire notre code.

Le mĂȘme JavaScript, uniquement dans le profil


Ces avantages ont un inconvénient. Il y a de bonnes raisons pour lesquelles les gens apprécient la séparation entre HTML et JavaScript. Comme je l'ai mentionné plus tÎt, l'abandon des fichiers HTML classiques complique le flux de travail pour quelqu'un qui n'a pas travaillé avec JavaScript auparavant. Ceux qui auparavant pouvaient apporter indépendamment des modifications à l'application web, doivent désormais acquérir des compétences complexes supplémentaires afin de maintenir leur autonomie, voire de se placer dans l'équipe.

Il existe Ă©galement des dĂ©fauts techniques. Par exemple, certains outils, tels que les linters et les analyseurs, n'acceptent que du HTML normal en entrĂ©e, et travailler avec des plug-ins JavaScript tiers peut ĂȘtre plus difficile Ă  la place. De plus, JavaScript n'est pas la meilleure langue, mais c'est une norme uniforme acceptĂ©e pour les navigateurs Web. De nouveaux outils et fonctionnalitĂ©s amĂ©liorent les choses, mais il y a encore des piĂšges que vous devez connaĂźtre avant de travailler avec.

Autre problĂšme potentiel: lorsque la structure sĂ©mantique de la page est divisĂ©e en composants abstraits, le dĂ©veloppeur peut cesser de penser aux Ă©lĂ©ments HTML qui seront gĂ©nĂ©rĂ©s en consĂ©quence. Balises HTML spĂ©cifiques telles que section et apart, ont leur propre sĂ©mantique, qui est perdue lors de l'utilisation de balises Ă  usage gĂ©nĂ©ral telles que div et span - mĂȘme si elles sont visuellement identiques sur la page. Ceci est particuliĂšrement important pour garantir la disponibilitĂ© de l'application Web pour diffĂ©rentes catĂ©gories d'utilisateurs.

Par exemple, cela affectera le comportement du lecteur d'Ă©cran pour les utilisateurs malvoyants. Ce ne sont peut-ĂȘtre pas les tĂąches les plus intĂ©ressantes pour le dĂ©veloppeur, mais les dĂ©veloppeurs JavaScript doivent toujours se rappeler que la prĂ©servation de la sĂ©mantique du HTML dans ce cas est la tĂąche la plus importante .

Besoin conscient vs tendance inconsciente


RĂ©cemment, l'utilisation de cadres dans chaque projet est devenue une tendance. Certaines personnes pensent que la sĂ©paration entre HTML et JavaScript est obsolĂšte, mais ce n'est pas le cas. Pour un site Web statique simple qui ne nĂ©cessite pas d'interaction utilisateur complexe, c'est tout Ă  fait juste. Les fans de React plus ardents peuvent ĂȘtre en dĂ©saccord avec moi ici, mais si tout votre JavaScript consiste Ă  crĂ©er une page Web non interactive, vous ne devriez pas l'utiliser. JavaScript ne se charge pas aussi rapidement que le HTML standard. Par consĂ©quent, si vous ne dĂ©finissez pas la tĂąche d'acquĂ©rir une nouvelle expĂ©rience de dĂ©veloppement ou d'amĂ©liorer la fiabilitĂ© du code, JavaScript ici fera plus de mal que de bien.

De plus, il n'est pas nécessaire d'écrire l'intégralité de votre site Web dans React. Ou Vue! Ou quoi d'autre est là ... Beaucoup de gens ne le savent pas, car tous les tutoriels montrent essentiellement comment utiliser React pour développer un site à partir de zéro. Si vous n'avez qu'un seul petit widget complexe sur un site Web simple, vous pouvez utiliser React pour un composant . Vous n'avez pas toujours à vous soucier du webpack, de Redux, de Gatsby ou de toute autre chose que quelqu'un recommande comme «meilleures pratiques».

Mais si l'application est assez complexe, l'utilisation d'une approche dĂ©clarative moderne en vaut vraiment la peine. React est-il la meilleure solution? Non. Il a dĂ©jĂ  de solides concurrents. Et puis de plus en plus apparaĂźtra ... Mais la programmation dĂ©clarative n'ira nulle part, et dans un nouveau cadre, cette approche sera probablement repensĂ©e et mise en Ɠuvre encore mieux.


All Articles