Fermer

janvier 13, 2022

Construire un éditeur de code Web —


Résumé rapide ↬

Si vous êtes un développeur qui envisage de créer une plate-forme nécessitant un éditeur de code sous une forme ou une autre, cet article est pour vous. Cet article explique comment créer un éditeur de code Web qui affiche le résultat en temps réel à l'aide de HTML, CSS et JavaScript.

Un éditeur de code Web en ligne est particulièrement utile lorsque vous n'avez pas la possibilité d'utiliser une application d'édition de code ou lorsque vous souhaitez essayer rapidement quelque chose sur le Web avec votre ordinateur ou même votre téléphone portable. Il s'agit également d'un projet intéressant sur lequel travailler, car le fait de savoir comment créer un éditeur de code vous donnera des idées sur la façon d'aborder d'autres projets qui nécessitent l'intégration d'un éditeur de code pour afficher certaines fonctionnalités.

En voici quelques-uns. Réagissez aux concepts que vous devrez connaître pour suivre cet article :

  • Hooks,
  • Structure des composants,
  • Composants fonctionnels,
  • Props.

Utilisation de CodeMirror

Nous serons en utilisant une bibliothèque nommée CodeMirror pour construire notre éditeur. CodeMirror est un éditeur de texte polyvalent implémenté en JavaScript pour le navigateur. Il est spécialement destiné à l'édition de code et est livré avec un certain nombre de modes de langue et add-ons pour des fonctionnalités d'édition plus avancées.

Une riche API de programmation et un système CSS theming est disponible pour personnaliser CodeMirror en fonction de votre application et l'étendre avec de nouvelles fonctionnalités. Il nous donne la possibilité de créer un éditeur de code riche qui s'exécute sur le Web et nous montre le résultat de notre code en temps réel.

Dans la section suivante, nous allons configurer notre nouveau projet React et installer les bibliothèques dont nous avons besoin. pour créer notre application Web.

Création d'un nouveau projet React

Commençons par créer un nouveau projet React. Dans votre interface de ligne de commande, accédez au répertoire dans lequel vous souhaitez créer votre projet, et créons une application React et nommez-la code_editor:

npx create-react-app code_editor

Après avoir créé notre nouvelle application React, naviguons jusqu'au répertoire de ce projet dans l'interface de ligne de commande :

cd code_editor

Il y a deux bibliothèques que nous devons installer ici : codemirror et react-codemirror2.

npm install codemirror react-codemirror2

Après avoir installé les bibliothèques dont nous avons besoin pour ce projet, créons nos onglets et activons le basculement entre les trois onglets qui apparaîtront dans notre éditeur (pour HTML, CSS et JavaScript ).

Plus après le saut ! Continuez à lire ci-dessous ↓

Composant de bouton

Au lieu de créer des boutons individuels, faisons du bouton un composant réutilisable. Dans notre projet, le bouton aurait trois instances, selon les trois onglets dont nous avons besoin.

Créez un dossier nommé components dans le dossier src. Dans ce nouveau dossier componentscréez un fichier JSX nommé Button.jsx.

Voici tout le code nécessaire dans le composant Button :[19659026]import React de 'react'
const Button = ({title, onClick}) => {
retourner (

)
}
Exporter le bouton par défaut

Voici une explication complète de ce que nous avons fait ci-dessus :

  • Nous avons créé un composant fonctionnel nommé Buttonque nous avons ensuite exporté.
  • Nous avons déstructuré title et onClick à partir des accessoires entrant dans le composant. Ici, title serait une chaîne de texte et onClick serait une fonction appelée lorsqu'un bouton est cliqué.
  • Ensuite, nous avons utilisé le bouton pour déclarer notre bouton et utilisé les attributs style pour styliser notre bouton afin qu'il soit présentable.
  • Nous avons ajouté l'attribut onClick et transmis notre déstructuré onClick la fonction props. Cela nous permet d'afficher le titre de manière dynamique, en fonction de l'accessoire transmis à l'instance du composant bouton lorsqu'il est appelé.

Maintenant que nous avons créé un composant bouton réutilisable, passons à autre chose et amenons notre composant dans App.js. Accédez à App.js et importez le composant de bouton nouvellement créé :

import Button from './components/Button';

Pour savoir quel onglet ou éditeur est ouvert, nous avons besoin d'un état de déclaration pour contenir la valeur de l'éditeur qui est ouvert. À l'aide du crochet React useStatenous allons configurer l'état qui stockera le nom de l'onglet de l'éditeur actuellement ouvert lorsque le bouton de cet onglet est cliqué.

Voici comment procéder :[19659026]import React, { useState } à partir de 'react';
importer './App.css' ;
importer le bouton de './components/Button' ;

fonction App() {
const [openedEditor, setOpenedEditor] = useState('html');
retourner (

);
}
export default App;

Ici, nous avons déclaré notre état. Il prend le nom de l'éditeur actuellement ouvert. Étant donné que la valeur html est transmise comme valeur par défaut de l'état, l'éditeur HTML serait l'onglet ouvert par défaut.

Passons et écrivons la fonction qui utilisera setOpenedEditor pour modifier la valeur de l'état lorsqu'un bouton d'onglet est cliqué.

Remarque : Deux onglets peuvent ne pas être ouverts en même temps, nous devrons donc en tenir compte lors de l'écriture de notre fonction.[19659003]Voici à quoi ressemble notre fonction, nommée onTabClick :

import React, { useState } from 'react' ;
importer './App.css' ;
importer le bouton de './components/Button' ;

fonction App() {
  ...

  const onTabClick = (nom de l'éditeur) => {
    setOpenedEditor(editorName);
  } ;

  retourner (
    
); } export default App;

Ici, nous avons passé un seul argument de fonction, qui est le nom de l'onglet actuellement sélectionné. Cet argument serait fourni partout où la fonction est appelée, et le nom pertinent de cet onglet serait transmis.

Créons trois instances de notre Bouton pour les trois onglets dont nous avons besoin :

[19659150]Bienvenue dans l'éditeur !
      

Voici ce que nous avons fait :

  • Nous avons commencé par ajouter une balise pessentiellement pour donner un peu de contexte à l'objet de notre application.
  • Nous avons utilisé un ]div pour envelopper nos boutons de tabulation. La balise div porte un className que nous utiliserons pour styliser les boutons dans un affichage de grille dans le fichier CSS plus loin dans ce didacticiel.
  • Ensuite, nous avons déclaré trois instances de la Composant Bouton. Si vous vous en souvenez, le composant Button prend deux accessoires, title et onClick. Dans chaque instance du composant Buttonces deux accessoires sont fournis.
  • L'accessoire title prend le titre de l'onglet.
  • Le onClick prop prend une fonction, onTabClickque nous venons de créer et qui prend un seul argument : le nom de l'onglet sélectionné.

En fonction de l'onglet actuellement sélectionné, nous utiliserions l'opérateur ternaire JavaScript pour afficher l'onglet conditionnellement. Cela signifie que si la valeur de l'état openedEditor est définie sur html (c'est-à-dire setOpenedEditor('html')), alors l'onglet de la section HTML devenir l'onglet actuellement visible. Vous comprendrez mieux cela comme nous le faisons ci-dessous :

...
retourner (
    
...
{ openEditor === 'html' ? (

L'éditeur html est ouvert

) : openEditor === 'css' ? (

L'éditeur CSS est ouvert!!!!!!

) : (

l'éditeur JavaScript est ouvert

) }
); ...

Passons en revue le code ci-dessus en anglais simple. Si la valeur de openedEditor est htmlaffichez la section HTML. Sinon, si la valeur de openedEditor est cssaffichez la section CSS. Sinon, si la valeur n'est ni html ni csscela signifie que la valeur doit être jscar nous n'avons que trois valeurs possibles pour le état openEditor ; alors, nous affichions l'onglet pour JavaScript.

Nous avons utilisé des balises de paragraphe (p) pour les différentes sections dans les conditions d'opérateur ternaire. Au fur et à mesure que nous procédons, nous allons créer les composants de l'éditeur et remplacer les balises p par les composants de l'éditeur eux-mêmes.

Nous avons déjà parcouru tout ce chemin ! Lorsqu'un bouton est cliqué, il déclenche l'action qui définit l'onglet qu'il représente sur truerendant cet onglet visible. Voici à quoi ressemble actuellement notre application :

Un GIF montrant la bascule d'onglet que nous avons actuellement.
Un GIF montrant la bascule d'onglet que nous avons actuellement. ( Grand aperçu)

Ajoutons un peu de CSS au conteneur div contenant les boutons. Nous voulons que les boutons soient affichés dans une grille, au lieu d'être empilés verticalement comme dans l'image ci-dessus. Accédez à votre fichier App.css et ajoutez le code suivant :

.tab-button-container{
  affichage : flexible ;
}

Rappelons que nous avons ajouté className="tab-button-container" comme attribut dans la balise div contenant les boutons à trois onglets. Ici, nous avons stylisé ce conteneur, en utilisant CSS pour définir son affichage sur flex. Voici le résultat :

Nous utilisons CSS pour définir son affichage sur flex
(Large preview)

Soyez fier de tout ce que vous avez fait pour en arriver là. Dans la section suivante, nous allons créer nos éditeurs, en remplaçant les balises p par eux.

Créer les éditeurs

Parce que nous avons déjà installé les bibliothèques sur lesquelles nous allons travailler dans notre CodeMirror éditeur, créons notre fichier Editor.jsx dans le dossier components.

components > Editor.jsx

Après avoir créé notre nouveau fichier, écrivons quelques premiers code dedans :

import React, { useState } à partir de « react » ;
importer « codemirror/lib/codemirror.css » ;
import { Contrôlé en tant que ControlledEditorComponent } depuis 'react-codemirror2' ;


const Editor = ({ language, value, setEditorState }) => {
  retourner (
    
) } exporter l'éditeur par défaut

Voici ce que nous avons fait :

  • Nous avons importé React avec le hook useState car nous allons en avoir besoin.
  • Nous avons importé le fichier CSS CodeMirror (qui provient de la bibliothèque CodeMirror que nous avons installé, vous n'avez donc pas besoin de l'installer d'une manière spéciale).
  • Nous avons importé Controlled de react-codemirror2en le renommant en ControlledEditorComponent pour que ce soit plus clair. Nous l'utiliserons sous peu.
  • Ensuite, nous avons déclaré notre composant fonctionnel Editoret nous avons une instruction return avec un div vide, avec un className dans l'instruction return pour le moment.

Dans notre composant fonctionnel, nous avons déstructuré certaines valeurs des accessoires, notamment languagevalue et setEditorState. Ces trois accessoires seraient fournis dans n'importe quelle instance de l'éditeur lorsqu'il est appelé dans App.js.

Utilisons ControlledEditorComponent pour écrire le code de notre éditeur. Voici ce que nous allons faire :

import React, { useState } depuis 'react' ;
importer « codemirror/lib/codemirror.css » ;
importer 'codemirror/mode/xml/xml' ;
importer 'codemirror/mode/javascript/javascript' ;
importer 'codemirror/mode/css/css' ;
import { Contrôlé en tant que ControlledEditorComponent } depuis 'react-codemirror2' ;


const Editor = ({ language, value, setEditorState }) => {
  retourner (
    
) } exporter l'éditeur par défaut

Parcourons ce que nous avons fait ici, en expliquant certains termes CodeMirror.

Les modes CodeMirror spécifient la langue pour laquelle un éditeur est destiné. Nous avons importé trois modes car nous avons trois éditeurs pour ce projet :

  1. XML : Ce mode est pour HTML. Il utilise le terme XML.
  2. JavaScript : Ceci (codemirror/mode/javascript/javascript) apporte le mode JavaScript.
  3. CSS : Ceci (codemirror/mode/css/css) apporte le mode CSS.

Remarque : Étant donné que l'éditeur est conçu comme un composant réutilisable, nous ne pouvons pas mettre de mode direct dans l'éditeur. Ainsi, nous fournissons le mode via la prop language que nous avons déstructurée. Mais cela ne change rien au fait que les modes doivent être importés pour fonctionner.

Ensuite, discutons des choses dans ControlledEditorComponent :

  • onBeforeChange
    C'est appelé à chaque fois que vous écrivez ou supprimez de l'éditeur. Pensez à cela comme au gestionnaire onChange que vous auriez normalement dans un champ de saisie pour suivre les modifications. En utilisant cela, nous pourrons obtenir la valeur de notre éditeur à chaque fois qu'il y aura un nouveau changement et l'enregistrer dans l'état de notre éditeur. Nous écrirons la fonction {handleChange} au fur et à mesure.
  • value = {value}
    Ceci n'est que le contenu de l'éditeur à un moment donné. Nous avons passé une prop déstructurée nommée value à cet attribut. Les accessoires value sont l'état contenant la valeur de cet éditeur. Cela serait fourni à partir de l'instance de l'éditeur.
  • className="code-mirror-wrapper"
    Ce nom de classe n'est pas un style que nous créons nous-mêmes. Il est fourni à partir du fichier CSS de CodeMirror, que nous avons importé ci-dessus.
  • options
    C'est un objet qui prend les différentes fonctionnalités que nous voulons que notre éditeur ait. Il existe de nombreuses options étonnantes dans CodeMirror. Regardons ceux que nous avons utilisés ici :
    • lineWrapping : true
      Cela signifie que le code doit passer à la ligne suivante lorsque la ligne est pleine.
    • lint : true
      Cela permet le linting.
    • mode : language
      Ce mode, comme indiqué ci-dessus, prend la langue pour laquelle l'éditeur va être utilisé. La langue a déjà été importée ci-dessus, mais l'éditeur va appliquer une langue basée sur la valeur language fournie à l'éditeur via la prop.
    • lineNumbers: true
      Cela spécifie que l'éditeur doit avoir des numéros de ligne pour chaque ligne.

Ensuite, nous pouvons écrire la fonction handleChange pour le gestionnaire onBeforeChange :

const handleChange = (editor, data, value) => {
    setEditorState(valeur);
}

Le gestionnaire onBeforeChange nous donne accès à trois choses : editor, data, value.

Nous n'avons besoin que de value car c'est ce que nous voulons passer notre prop setEditorState. La prop setEditorState représente la valeur définie pour chaque état que nous avons déclaré dans App.jscontenant la valeur pour chaque éditeur. Au fur et à mesure que nous avançons, nous verrons comment transmettre cela en tant qu'accessoire au composant Editor.

Ensuite, nous ajouterons une liste déroulante qui nous permettra de sélectionner différents thèmes pour l'éditeur. Examinons donc les thèmes dans CodeMirror.

CodeMirror Themes

CodeMirror a plusieurs thèmes parmi lesquels nous pouvons sélectionner. Visitez le site officiel pour voir des démos des différents thèmes disponibles. Faisons une liste déroulante avec différents thèmes parmi lesquels l'utilisateur peut choisir dans notre éditeur. Pour ce tutoriel, nous allons ajouter cinq thèmes, mais vous pouvez en ajouter autant que vous le souhaitez.

Tout d'abord, importons nos thèmes dans le composant Editor.js :

import 'codemirror /theme/dracula.css';
importer 'codemirror/theme/material.css';
importer 'codemirror/theme/mdn-like.css';
importer 'codemirror/theme/the-matrix.css';
import 'codemirror/theme/night.css';

Ensuite, créez un tableau de tous les thèmes que nous avons importés :

const themeArray = ['dracula', 'material', 'mdn-like', 'the-matrix', 'night']

Déclarons un useState hook pour conserver la valeur du thème sélectionné et définissez le thème par défaut comme dracula:

const [theme, setTheme] = useState("dracula")

Créons la liste déroulante :

. ..
retourner (
    
// le reste du code se trouve ci-dessous...
) ...

Dans le code ci-dessus, nous avons utilisé la balise HTML label pour ajouter une étiquette à notre liste déroulante, puis ajouté la balise HTML select pour créer notre liste déroulante. La balise option dans l'élément select définit les options disponibles dans la liste déroulante.

Parce que nous devions remplir la liste déroulante avec les noms de thème dans le themeArray que nous avons créé, nous avons utilisé la méthode de tableau .map pour mapper themeArray et afficher les noms individuellement à l'aide de la balise option.

Attendez — nous' n'avez pas fini d'expliquer le code ci-dessus. Dans la balise d'ouverture selectnous avons transmis l'attribut onChange pour suivre et mettre à jour l'état theme chaque fois qu'une nouvelle valeur est sélectionnée dans la liste déroulante. Chaque fois qu'une nouvelle option est sélectionnée dans la liste déroulante, la valeur est obtenue à partir de l'objet qui nous est renvoyé. Ensuite, nous utilisons le setTheme de notre hook d'état pour définir la nouvelle valeur comme étant la valeur que l'état contient.

À ce stade, nous avons créé notre liste déroulante, configuré l'état de notre thème, et écrit notre fonction pour définir l'état avec la nouvelle valeur. La dernière chose que nous devons faire pour que CodeMirror utilise notre thème est de transmettre le thème à l'objet options dans ControlledEditorComponent. Dans l'objet optionsajoutons une valeur nommée themeet définissons sa valeur sur la valeur de l'état pour le thème sélectionné, également nommé theme.

Voici à quoi ressemblerait ControlledEditorComponent :

Maintenant, nous avons créé une liste déroulante de différents thèmes qui peuvent être sélectionnés dans l'éditeur.

Voici le code complet. dans Editor.js ressemble à l'instant :

import React, { useState } de 'react' ;
importer « codemirror/lib/codemirror.css » ;
importer 'codemirror/theme/dracula.css';
importer 'codemirror/theme/material.css';
importer 'codemirror/theme/mdn-like.css';
importer 'codemirror/theme/the-matrix.css';
importer 'codemirror/theme/night.css';
importer 'codemirror/mode/xml/xml' ;
importer 'codemirror/mode/javascript/javascript' ;
importer 'codemirror/mode/css/css' ;
import { Contrôlé en tant que ControlledEditorComponent } depuis 'react-codemirror2' ;


const Editor = ({ language, value, setEditorState }) => {
  const [theme, setTheme] = useState("dracula")
  const handleChange = (éditeur, données, valeur) => {
    setEditorState(valeur);
  }
  const themeArray = ['dracula', 'material', 'mdn-like', 'the-matrix', 'night']
  retourner (
    
) } exporter l'éditeur par défaut

Il n'y a qu'un seul className que nous devons styliser. Accédez à App.css et ajoutez le style suivant :

.editor-container{
  rembourrage supérieur : 0,4 % ;
}

Maintenant que nos éditeurs sont prêts, revenons à App.js et utilisons-les là-bas.

src > App.js

La première chose que nous devons faire est d'importer le Composant Editor.js ici :

import Editor from './components/Editor';

Dans App.jsdéclarons les états qui contiendront le contenu des éditeurs HTML, CSS et JavaScript, respectivement.

const [html, setHtml] = useState('');
const [css, setCss] = useState('');
const [js, setJs] = useState('');

Si vous vous en souvenez, nous devrons utiliser ces états pour conserver et fournir le contenu de nos éditeurs.

Ensuite, remplaçons le paragraphe (p) que nous avons utilisées pour les balises HTML, CSS et JavaScript dans les rendus conditionnels avec les composants de l'éditeur que nous venons de créer, et nous transmettrons également la prop appropriée à chaque instance du composant de l'éditeur :

fonction Application() {
  ...
  retourner (
    

Bienvenue dans l'edior

// C'est ici que se trouve le conteneur des boutons d'onglet...
{ htmlL'éditeur est ouvert ? ( ) : cssEditorIsOpen ? ( ) : ( ) }
); } export default App;

Si vous avez suivi jusqu'à présent, vous comprendrez ce que nous avons fait dans le bloc de code ci-dessus.

Le voici en anglais simple : nous avons remplacé le p balises (qui étaient là en tant qu'espaces réservés) avec des instances des composants de l'éditeur. Ensuite, nous avons fourni leurs accessoires languagevalue et setEditorStaterespectivement, pour correspondre à leurs états correspondants.

Nous sommes arrivés jusqu'ici ! Voici à quoi ressemble notre application maintenant :

La façon dont notre application ressemble maintenant
(Grand aperçu)

Introduction aux Iframes

Nous utiliserons des cadres intégrés (iframes) pour afficher le résultat du code saisi dans l'éditeur.

Selon MDN :

L'élément HTML Inline Frame () représente un contexte de navigation imbriquéincorporant une autre page HTML dans la page actuelle.

Comment fonctionnent les Iframes dans React

Les Iframes sont normalement utilisés avec du HTML brut. L'utilisation d'Iframes avec React ne nécessite pas beaucoup de changements, le principal étant de convertir les noms d'attributs en camelcase. Un exemple de ceci est que srcdoc deviendrait srcDoc.

L'avenir des Iframes sur le Web

Les Iframes continuent d'être très utiles dans le développement Web. Quelque chose que vous voudrez peut-être vérifier, ce sont les portails. Comme l'explique Daniel Brain :

« Les portails introduisent un nouvel ensemble puissant de capacités dans ce mélange. Maintenant, il est possible de créer quelque chose qui ressemble à un iframe, qui peut s'animer et se transformer de manière transparente et prendre en charge toute la fenêtre du navigateur. "

L'une des choses que Portals essaie de résoudre est le problème de la barre d'URL. Lors de l'utilisation d'iframe, les composants rendus dans l'iframe ne portent pas d'URL unique dans la barre d'adresse ; en tant que tel, cela peut ne pas être génial pour l'expérience utilisateur, selon le cas d'utilisation. Les portails valent le détour, et je vous suggère de le faire, mais comme ce n'est pas l'objet de notre article, c'est tout ce que je vais en dire ici.

Créer l'Iframe pour héberger notre résultat

Poursuivons notre tutoriel en créant un iframe pour héberger le résultat de nos éditeurs.

return (
    
// ...
);

Ici, nous avons créé l'iframe et l'avons hébergé dans une balise conteneur div. Dans l'iframe, nous avons passé certains attributs dont nous avons besoin :

  • srcDoc
    L'attribut srcDoc est écrit en camelcase car c'est ainsi que l'on écrit les attributs iframe dans React. Lors de l'utilisation d'un iframe, nous pouvons soit intégrer une page Web externe sur la page, soit afficher le contenu HTML spécifié. Pour charger et intégrer une page externe, nous utiliserions à la place la propriété src. Dans notre cas, nous ne chargeons pas de page externe ; nous voulons plutôt créer un nouveau document HTML interne qui héberge notre résultat ; pour cela, nous avons besoin de l'attribut srcDoc. Cet attribut prend le document HTML que nous voulons intégrer (nous ne l'avons pas encore créé, mais nous le ferons bientôt).
  • title
    L'attribut title est utilisé pour décrire le contenu du cadre en ligne.[19659005]bac à sable
    Cette propriété a de nombreuses fonctions. Dans notre cas, nous l'utilisons pour permettre aux scripts de s'exécuter dans notre iframe avec la valeur allow-scripts. Parce que nous travaillons avec un éditeur JavaScript, cela s'avérerait utile rapidement.
  • frameBorder
    Cela définit simplement l'épaisseur de la bordure de l'iframe.
  • width et height
    Cela définit la largeur et la hauteur de l'iframe.

Ces termes devraient maintenant avoir plus de sens pour vous. Passons à autre chose et déclarons l'état qui contiendra le document modèle HTML pour srcDoc. Si vous regardez attentivement le bloc de code ci-dessus, vous verrez que nous avons transmis une valeur à l'attribut srcDoc : srcDoc={srcDoc}. Utilisons notre hook React useState() pour déclarer l'état srcDoc. Pour ce faire, dans le fichier App.jsallez à l'endroit où nous avons défini les autres états et ajoutez celui-ci :

const [srcDoc, setSrcDoc] = useState(` `);

Maintenant que nous ont créé l'état, la prochaine chose à faire est d'afficher le résultat dans l'état chaque fois que nous tapons dans l'éditeur de code. Mais ce que nous ne voulons pas, c'est re-rendre le composant à chaque pression de touche. Dans cet esprit, continuons.

Configuration de l'Iframe pour afficher le résultat

Chaque fois qu'il y a un changement dans l'un des éditeurs pour HTML, CSS et JavaScript, respectivement, nous voulons useEffect() à être déclenché, et cela rendra le résultat mis à jour dans l'iframe. Écrivons useEffect() pour le faire dans le fichier App.js :

Tout d'abord, importez le hook useEffect() :

import React , { useState, useEffect } de 'react' ;

Écrivons useEffect() comme ceci :

useEffect(() => {
    const timeOut = setTimeout(() => {
      setSrcDoc(
        `
          
            ${html}  `
      )
    }, 250);
    return() => clearTimeout(timeOut)
  }, [html, css, js])

Ici, nous avons écrit un hook useEffect() qui s'exécutera toujours chaque fois que la valeur que nous avons déclarée pour les éditeurs HTML, CSS et JavaScript est modifiée ou mise à jour.[19659003]Pourquoi avons-nous besoin d'utiliser setTimeout() ? Eh bien, si nous écrivions ceci sans cela, chaque fois qu'une seule touche est enfoncée dans un éditeur, notre iframe serait mis à jour, et ce n'est pas génial pour les performances en général. Nous utilisons donc setTimeout() pour retarder la mise à jour de 250 millisecondes, ce qui nous laisse suffisamment de temps pour savoir si l'utilisateur est toujours en train de taper. C'est-à-dire que chaque fois que l'utilisateur appuie sur une touche, il redémarre le décompte, de sorte que l'iframe ne sera mis à jour que lorsque l'utilisateur est inactif (sans taper) pendant 250 millisecondes. C'est un bon moyen d'éviter d'avoir à mettre à jour l'iframe à chaque fois qu'une touche est enfoncée.

La prochaine chose que nous avons faite ci-dessus a été de mettre à jour srcDoc avec les nouvelles modifications. Le composant srcDoccomme nous l'avons expliqué ci-dessus, restitue le contenu HTML spécifié dans l'iframe. Dans notre code, nous avons passé un modèle HTML, prenant l'état html qui contient le code que l'utilisateur a tapé dans l'éditeur HTML et le plaçant entre les balises body de notre modèle. Nous avons également pris l'état css qui contient les styles que l'utilisateur a saisis dans l'éditeur CSS, et nous l'avons passé entre les balises style. Enfin, nous avons pris l'état js qui contient le code JavaScript que l'utilisateur a tapé dans l'éditeur JavaScript, et nous l'avons passé entre les balises script.

Remarquez que dans le paramétrage setSrcDocnous avons utilisé des backticks (` `) au lieu de guillemets normaux (' '). En effet, les backticks nous permettent de transmettre les valeurs d'état correspondantes, comme nous l'avons fait dans le code ci-dessus.

L'instruction return dans le hook useEffect() est une fonction de nettoyage qui efface setTimeout() lorsqu'il est terminé, pour éviter les fuites de mémoire. La documentation a plus sur useEffect.

Voici à quoi ressemble notre projet en ce moment :

À quoi ressemble notre projet en ce moment
( Grand aperçu)

Modules complémentaires CodeMirror

Avec les modules complémentaires CodeMirror, nous pouvons améliorer notre éditeur avec davantage de fonctionnalités que nous trouverions dans d'autres éditeurs de code. Passons en revue un exemple de balises fermantes ajoutées automatiquement lorsqu'une balise ouvrante est tapée, et un autre exemple de crochet se fermant automatiquement lorsque le crochet ouvrant est entré :

La première chose à faire est d'importer l'addon pour cela dans notre Fichier App.js :

import 'codemirror/addon/edit/closetag' ;
import 'codemirror/addon/edit/closebrackets';

Passons-le dans les options ControlledEditorComponent :

Maintenant, voici ce que nous avons :

La façon dont notre projet looks
(Large preview)

Vous pouvez ajouter une tonne de ces addons à votre éditeur pour lui donner des fonctionnalités plus riches. Nous ne pourrions probablement pas les parcourir tous ici.

Maintenant que nous avons terminé, discutons brièvement des choses que nous pourrions faire pour améliorer l'accessibilité et les performances de notre application.

Performances et accessibilité. of the Solution

En regardant notre éditeur de code Web, certaines choses pourraient certainement être améliorées.

Parce que nous avons prêté attention principalement à la fonctionnalité, nous avons peut-être un peu négligé la conception. Pour une meilleure accessibilité, voici certaines choses que vous pouvez faire pour améliorer cette solution :

  1. Vous pouvez définir une classe active sur le bouton de l'éditeur actuellement ouvert. Mettre le bouton en surbrillance améliorerait l'accessibilité en donnant aux utilisateurs une indication claire de l'éditeur sur lequel ils travaillent actuellement.
  2. Vous souhaiterez peut-être que l'éditeur occupe plus d'espace à l'écran que ce que nous avons ici. Une autre chose que vous pouvez essayer est de faire apparaître l'iframe en cliquant sur un bouton qui est ancré quelque part sur le côté. Doing so would give the editor more screen space.
  3. This sort of editor would be useful for people who want to run a quick exercise on their mobile device, so fully adapting it to mobile would be necessary (not to mention both of the points about mobile above).
  4. Currently, we are able to switch the theme of the editor component from among the multiple themes we’ve loaded in, but the general theme of the page remains the same. You could enable the user to switch between a dark and light theme for the entire layout. This would be good for accessibility, relieving the strain on people’s eyes from looking at a bright screen for too long.
  5. We didn’t look at security issues with our iframe, mainly because we were loading an internal HTML document in the iframe, rather than an external document. So we don’t need to consider this too carefully because iframes are a good fit for our use case.
  6. With iframes, another consideration would be page-loading time, because the content being loaded in the iframe would normally be out of your control. In our app, this isn’t an issue because our iframe content isn’t external.

Performance and accessibility are worth a lot of consideration when you’re building any application because they will determine how useful and usable your application is to its users.

Shedrack has done a good job of explaining methods for improving and optimizing performance in React apps. It’s worth checking out!

Conclusion

Working through different projects helps us to learn about a wide range of subjects. Now that you’ve gone through this article, feel free to expand upon your experience by experimenting with more add-ons to make the code editor richer, revamping the UI, and fixing the accessibility and performance concerns outlined above.

Here’s the demo on Codesandbox:

Smashing Editorial" width="35" height="46" loading="lazy" decoding="async(ks, vf, yk, il, al)




Source link