Premiers pas avec la bibliothèque React Javascript
Publié: 2022-02-16Si vous passez du temps dans le monde WordPress, vous avez probablement rencontré Zac Gordon. Zac est un enseignant enthousiaste et charmant qui se concentre sur Javascript dans WordPress. Il a emprunté l'expression "Learn Javascript Deeply" de Matt Mullenweg et en a fait son slogan personnel.
Au cours des dernières années, Zac a produit des cours vidéo, des conférences en ligne, des discussions en direct et des podcasts qui visent à vous apprendre à utiliser Javascript dans WordPress.
Je suis ravi de dire que nous travaillons avec Zac sur un livre, "React Explained". React est la bibliothèque que l'équipe WordPress a choisie pour le nouvel éditeur Gutenberg. Ils ne sont pas seuls - Drupal et Magento ont également choisi React.
Zac tweete en direct ses progrès d'écriture à @zgordon sur Twitter. Vous pouvez également entendre Zac parler de React sur le podcast OSTraining.
Dans cet extrait du livre, Zac vous donne un aperçu de haut niveau de React et de quelques concepts clés.
Qu'est-ce que React ?
Prêt à l'emploi, React est une bibliothèque permettant de créer des interfaces utilisateur.
Bien que React soit une bibliothèque JavaScript, les interfaces construites par React sont agnostiques.
Plusieurs bibliothèques compagnons React existent afin de faire fonctionner les interfaces que vous construisez dans le navigateur, sur le serveur, dans les applications natives et même dans les environnements 360 et VR. Dans ce livre, nous nous concentrons sur le travail avec ReactDOM, la bibliothèque qui gère l'ajout des interfaces que nous construisons avec React aux sites Web et applications côté client. ReactDomServer, ReactNative et React360 sont également des bibliothèques que vous voudrez peut-être explorer pour utiliser les interfaces React dans d'autres environnements.
En plus de fournir des fonctions d'assistance pour la création d'interfaces, l'architecture de React vous permet de gérer les interactions avec vos interfaces, qu'il s'agisse de la gestion des événements, des appels d'API, de la gestion de l'état, des mises à jour de l'interface ou d'interactions plus complexes.
React ne fournit pas autant de fonctions d'assistance que certains frameworks JavaScript. C'est en grande partie pourquoi nous appelons React une bibliothèque et non un framework. Vous aurez toujours besoin d'écrire beaucoup de JavaScript vanille lorsque vous travaillez avec React.
Explication de l'architecture des composants React
Un composant est un morceau de code indépendant et réutilisable (créé via une fonction ou une classe).
React utilise une architecture de composants pour créer des interfaces utilisateur et organiser le code. Le fichier principal d'une simple application React peut ressembler à ceci.
// Importer React et d'autres composants importer React depuis 'react' ; importer { rendre } à partir de 'react-dom' ; importer l'en-tête de './En-tête' ; importer MainContent depuis './MainContent' ; importer le pied de page de './Footer' ; fonction App(){ retourner ( <div className="app"> <En-tête /> <Contenu principal /> <Pied de page /> </div> ); } ReactDOM.render( <App />, document.getElementById("root"));
Nous pouvons voir ici quelques composants en cours d'utilisation. <Header />, <MainContent /> et <Footer /> sont tous des composants. La fonction App() est également un composant et nous pouvons voir sur la dernière ligne de cet exemple comment nous pouvons utiliser la bibliothèque ReactDOM et la méthode ReactDOM.render() pour gérer l'ajout de l'interface utilisateur que nous construisons à une page Web.
Si nous creusons à l'intérieur des composants <Header />, <MainContent /> et <Footer />, nous verrions probablement l'utilisation de plus de composants ainsi que ce qui ressemble à du balisage HTML.
importer React depuis "react" ; importer l'annonce depuis "../Annonce" ; importer le logo depuis "../assets/logo.svg" ; exporter la fonction par défaut Header() { retourner ( <header className="app-header"> <Annonce /> <img src={logo} className="app-logo" alt="logo" /> <h1 className="app-title">Nom du site</h1> </header> ); }
Dans ce composant <Header /> ci-dessus, nous pouvons voir que nous ajoutons un autre composant appelé <Ad />. La plupart des applications React contiennent plusieurs couches d'imbrication de composants comme nous le voyons avec <App />, <Header /> et <Ad />.
Nous voyons également l'utilisation d'éléments HTML dans notre code React. Ceci est possible grâce à une bibliothèque appelée JSX, qui vous permet d'écrire du "balisage HTML" directement dans votre JavaScript. Étant donné que nous utilisons React pour créer des interfaces utilisateur et que les interfaces utilisateur sur le Web impliquent un balisage HTML, il est logique que nous voyions des éléments de type HTML dans nos composants d'interface utilisateur. Nous explorerons JSX en profondeur dans ce livre.
Si nous examinons un code d'une simple application React construite à l'aide de React 360, la bibliothèque VR de React, les composants réels que nous appelons seraient différents, mais l'architecture des composants est toujours présente.
importer React depuis 'react' ; importer { Texte, Voir, Bouton Vr, } de 'réagir-360' ; class Slideshow étend React.Component { // Code supprimé par souci de brièveté retourner ( <Style de vue={styles.wrapper}> <Style de vue={styles.controls}> <VrButton onClick={this.prevPhoto}> <Texte>{'Précédent'}</Texte> </VrButton> <VrButton onClick={this.nextPhoto}> <Texte>{'Suivant'}</Texte> </VrButton> <Afficher> <Text style={styles.title}>{current.title}</Text> </Afficher> </Afficher> ); }
Le code ci-dessus crée plusieurs couches de vues à 360 degrés avec des boutons et du texte superposés. Bien que le code réel puisse ne pas avoir tout son sens, il doit être clair que nous avons plusieurs composants imbriqués représentant la vue, les boutons et le texte.
C'est un bon exemple car vous pouvez voir comment les mêmes composants sont réutilisés de différentes manières en leur passant des paramètres différents, ou ce que React appelle des props. Comprendre comment les données transitent par les composants React est important pour comprendre l'architecture de composant typique utilisée pour la construction avec React.
Réagir au flux de données expliqué
React suit une convention d'obtention et de définition des données au point le plus élevé nécessaire dans une hiérarchie de composants pour que les données passent dans une direction à sens unique à travers une application. Jetons un coup d'œil à cet exemple et imaginons certains des types de données dont nous aurions besoin pour divers composants.
fonction App() { retourner( <Réagir.Fragment> <En-tête /> <Contenu /> <Barre latérale /> <Pied de page /> </React.Fragment> ); }
Quelque chose comme le nom du site peut devoir être disponible à la fois pour le <Header /> et le <Footer />. Le contenu principal de la page particulière devrait être transmis à <Content />. Certaines données de widget supplémentaires devront peut-être aller dans <Sidebar />.
fonction App() { const siteTitle = getSiteTitle(); const widgets = getWidgets(); const mainContent = getPageContent(); retourner( <Réagir.Fragment> <Header siteTitle={siteTitle} /> <Contenu mainContent={mainContent} /> <widgets de la barre latérale={widgets} /> <Footer siteTitle={siteTitle} /> </React.Fragment> ); }
Cette convention consistant à créer des noms d'attributs et à leur attribuer une valeur est la façon dont nous transmettons les données dans un composant.
Maintenant, le <Header /> et le <Footer /> ont accès au siteTitle, le <Content /> a accès au mainContent et le <Sidebar /> a accès aux widgets dont il a besoin.
Une remarque importante est que ce modèle de transmission de données dans un composant ne transmet les données qu'à un niveau. Les composants à l'intérieur de <Header /> n'auront pas automatiquement accès à siteTitle.

fonction En-tête (accessoires) { retourner( <en-tête> <p>Nous pouvons voir le {props.siteTitle} ici.</p> <PageHeader siteTitle={props.siteTitle} /> <PageSubHeader /> </header> ); }
Vous pouvez voir ici qu'à l'intérieur de <Header /> nous pouvons appeler props.siteTitle et avoir accès à cette valeur que nous lui avons transmise. Cependant, si nous voulions avoir accès à siteTitle dans le composant <PageHeader />, nous devions également transmettre manuellement ces informations.
Lorsqu'un composant reçoit une valeur en tant que prop, il ne doit pas la modifier. Les accessoires doivent passer par une arborescence de composants en tant que données immuables. Cela garantit que tout composant qui fait référence à un accessoire fait référence à la même valeur que son parent de composants enfants.
La valeur d'un accessoire ne doit être modifiée que dans le composant qui a initialement défini la valeur de l'accessoire et commencé à la transmettre à travers l'arborescence des composants. Dans notre exemple de code ci-dessus, le composant <App /> peut modifier la valeur de siteTitle, mais pas les composants <Header /> ou <PageHeader />.
Pour comprendre le flux de mise à jour des données dynamiques dans une application React, il faut discuter de l'état et de la manière dont les gestionnaires d'événements peuvent être transmis en tant qu'accessoires.
Explication des états des composants React
Comme nous l'avons appris, les données circulent inchangées à travers les composants en tant qu'accessoires. Les données sont définies au niveau du composant le plus élevé de l'arborescence nécessaire pour que tous les composants enfants reçoivent les informations nécessaires en tant qu'accessoires.
Dans certains cas, ces données sont reçues une seule fois et n'ont pas besoin d'être modifiées. Dans de nombreux cas, cependant, ces données doivent rester dynamiques et avoir la possibilité de se mettre à jour à tout moment et de refléter cette mise à jour dans tous les composants enfants.
Pour suivre les données qui changent dans React, nous avons un objet d'état React et un ensemble de fonctions d'assistance pour mettre à jour la valeur d'état.
Voici un exemple de compteur qui se mettrait à jour tout seul. La valeur du compteur est une valeur dynamique au sein de ce composant et constitue donc un bon exemple du moment où s'appuyer sur l'état. Notez que pour créer des composants avec état, nous devons utiliser des classes JavaScript plutôt que des fonctions.
le compteur de classe étend le composant { état= { compteur : 0 } ; handleCount = () => { this.setState({ compteur : this.state.counter + 1 }); } ; rendu() { retourner ( <div> <h1>{this.state.counter}</h1> <button onClick={this.handleCount}>Comptez !!</button> </div> ); } }
Maintenant, il est important de noter que cet état est limité à ce composant uniquement. La valeur de l'état dans le compteur ne serait pas disponible pour les composants enfants ou parents.
Ainsi, dans un exemple plus complexe, comme ci-dessous, nous devrions transmettre la valeur de counter down en tant que prop dans l'élément enfant.
le compteur de classe étend le composant { état= { compte:0 } ; handleCount = () => { this.setState({ compter : this.state.count + 1 }); } ; rendu() { retourner ( <div> <PageHeader count={this.state.count} /> <button onClick={this.handleCount}>Comptez !!</button> </div> ); } }
Le prop count <PageHeader /> est mis à jour chaque fois que nous mettons à jour l'état dans le composant <Counter />
function Tête de page(accessoires) { renvoie <h1>{props.count}</h1> ; }
La bonne chose à propos de cette approche est que chaque fois que l'état est mis à jour, une nouvelle valeur sera automatiquement transmise à tous les composants enfants avec la valeur d'un accessoire défini sur state.
Cela nous permet d'avoir un point de vérité unique pour les données dynamiques. La source de vérité est la valeur en état, gérée à partir d'un seul composant. Toutes les instances de cette valeur dans les composants enfants sont des valeurs immuables reçues en tant qu'accessoires qui ne doivent pas être modifiées en dehors de ce composant.
Les composants qui apparaissent au-dessus de ce composant dans la hiérarchie n'auraient pas accès à ces données car elles ne sont transmises que via des accessoires. Nous voyons à nouveau pourquoi nous essayons de définir et de gérer l'état des composants situés plus haut dans la hiérarchie afin que les données soient disponibles pour tout ce qui en a besoin.
Il existe d'autres modèles d'architecture, comme les composants d'ordre supérieur et l'API de contexte, qui évitent de devoir transmettre manuellement des tonnes d'accessoires via votre application. Nous les explorerons plus en profondeur plus tard. Pour l'instant, nous voulons nous assurer que nous comprenons cet aperçu de haut niveau de la façon dont les choses fonctionnent généralement avant de commencer à prendre des raccourcis.
Mise à jour des états des composants dans React
Maintenant, que se passe-t-il lorsque nous voulons déclencher la mise à jour de l'état à partir d'un composant enfant ?
Imaginez, par exemple, qu'avec l'exemple ci-dessus, nous voulions avoir un composant <Button /> plutôt qu'un bouton codé en dur dans notre composant principal <Counter /> ? Ceci est en fait assez courant dans les applications complexes.
La solution à cela, dans le monde React, consiste à transmettre la fonction de gestionnaire d'événements qui met à jour l'état avec setState comme accessoire. Ensuite, il peut être appelé à partir de n'importe quel composant enfant, mais l'action aura lieu dans le composant d'origine qui définit l'état et a également la possibilité de le mettre à jour. D'autres modèles existent pour cela, mais cette approche est la plus basique.
Si vous n'êtes pas familiarisé avec le passage de fonctions en tant que paramètres, il s'agit d'un JavaScript vanille tout à fait valide.
Une fois l'état mis à jour, il sera transmis à travers la hiérarchie des composants via les accessoires.
Voici un exemple de ce à quoi cela ressemblerait.
le compteur de classe étend le composant { état= { compte:0 } ; handleCount = () => { this.setState({ compter : this.state.count + 1 }); } ; rendu() { retourner ( <div> <PageHeader count={this.state.count} /> <Button handleCount={this.handleCount} /> </div> ); } } function Tête de page( props ) { retourner( <h1>{props.count}</h1> ); } Bouton de fonction (accessoires) { retourner( <button onClick={props.handleCount}>Comptez!!</button> ); }
Ici, nous pouvons voir un exemple simple de la façon dont React gère le flux de données. Il existe un point de vérité unique pour les données. Cela existe dans l'état défini et mis à jour à partir d'un seul composant. Les données sont transmises dans un flux à sens unique à travers une arborescence de composants imbriquée via des accessoires.
Si l'état doit être mis à jour à partir d'un composant autre que celui où il a été défini à l'origine, un gestionnaire d'événements peut être transmis au composant enfant nécessaire en tant que prop. Ainsi, les données restent immuables et circulent dans un sens, car même si un composant enfant déclenche une modification, cette modification a lieu plus haut dans le composant d'origine.
Lorsque nous attribuons la valeur d'un accessoire à quelque chose à partir de l'état, comme ci-dessous, cette valeur d'accessoire sera automatiquement mise à jour chaque fois que l'état change.
<PageHeader counter={this.state.count} />
Tout autre composant enfant faisant référence à cette valeur prop recevra également la mise à jour automatiquement. C'est la beauté du flux de données dans React.
Cela peut prendre un peu de temps pour s'y habituer en fonction de la façon dont vous avez abordé des problèmes comme ceux-ci avec JavaScript dans le passé. Cependant, tout cela devrait servir de bon point de départ pour que nous puissions approfondir l'explication de React.