Tutoriel React, partie 9: Propriétés des composants

Dans la partie d'aujourd'hui de la traduction du didacticiel React, nous parlerons des propriétés des composants. C'est l'un des concepts les plus importants reflétés dans cette bibliothèque.

image

Partie 1: aperçu du cours, raisons de la popularité de React, ReactDOM et JSX
Partie 2: composants fonctionnels
Partie 3: fichiers composants, structure du projet
Partie 4: composants parent et enfant
Partie 5: début des travaux sur une application TODO, les bases du style
Partie 6: sur certaines fonctionnalités du cours, JSX et JavaScript
Partie 7: styles en ligne
Partie 8: poursuite des travaux sur l'application TODO, familiarité avec les propriétés des composants
Partie 9: propriétés des composants
Partie 10: Atelier sur l'utilisation des propriétés et du style des composants
Partie 11: génération de balisage dynamique et méthode des tableaux de cartes
Partie 12: atelier, troisième étape de travail sur une application TODO
Partie 13: composants basés sur les classes
Partie 14: atelier sur les composants basés sur les classes, état des composants
Partie 15: ateliers santé composante
Partie 16: quatrième étape de travail sur une application TODO, gestion d'événements
Partie 17: cinquième étape de travail sur une application TODO, modifiant l'état des composants
Partie 18: la sixième étape de travail sur une application TODO
Partie 19: méthodes du cycle de vie des composants
Partie 20: la première leçon de rendu conditionnel
Partie 21: deuxième leçon et atelier sur le rendu conditionnel
Partie 22: la septième étape des travaux sur une application TODO, téléchargement de données depuis des sources externes
Partie 23: première leçon sur l'utilisation des formulaires
Partie 24: Deuxième leçon sur les formulaires
Partie 25: Atelier sur l'utilisation des formulaires
Partie 26: architecture d'application, modèle de conteneur / composant
Partie 27: projet de cours

Leçon 19. Propriétés des composants dans React


Original

Créez un nouveau projet à l'aide de create-react-app et modifiez le code de plusieurs fichiers standard à partir du dossier src .

Voici le code du fichier index.js :

 import React from "react" import ReactDOM from "react-dom" import "./index.css" import App from "./App" ReactDOM.render(<App />, document.getElementById("root")) 

Voici les styles décrits dans le fichier index.css :

 body { margin: 0; } .contacts { display: flex; flex-wrap: wrap; } .contact-card { flex-basis: 250px; margin: 20px; } .contact-card > img { width: 100%; height: auto; } .contact-card > h3 { text-align: center; } .contact-card > p { font-size: 12px; } 

Voici le code trouvé dans le fichier App.js :

 import React from "react" function App() {   return (       <div className="contacts">           <div className="contact-card">               <img align="center" src="http://placekitten.com/300/200"/>               <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>               <p>Phone: (212) 555-1234</p>               <p>Email: mr.whiskaz@catnap.meow</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/200"/>               <h3><font color="#3AC1EF">▍Fluffykins</font></h3>               <p>Phone: (212) 555-2345</p>               <p>Email: fluff@me.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/300"/>               <h3><font color="#3AC1EF">▍Destroyer</font></h3>               <p>Phone: (212) 555-3456</p>               <p>Email: ofworlds@yahoo.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/200/100"/>               <h3><font color="#3AC1EF">▍Felix</font></h3>               <p>Phone: (212) 555-4567</p>               <p>Email: thecat@hotmail.com</p>           </div>       </div>   ) } export default App 

Voici à quoi ressemblera cette application dans un navigateur.


Page d'application dans le navigateur

Après avoir analysé le code et l'apparence de l'application, nous pouvons conclure qu'il serait bien d'utiliser des composants spéciaux pour afficher des cartes avec des informations sur les animaux. Maintenant, ces éléments sont formés au moyen du composant App . Compte tenu de ce dont nous avons parlé dans les classes précédentes, vous pouvez aller plus loin - pensez à un composant universel qui peut être personnalisé en lui passant des attributs ou des propriétés.

Dans notre application, il y a des cartes avec des images de chats, leurs noms et les coordonnées de leurs propriétaires (ou peut-être eux-mêmes) - un téléphone et une adresse e-mail. Afin de créer un composant qui deviendra plus tard la base de toutes ces cartes, vous pouvez prendre l'un des fragments de balisage renvoyés par le composant App . Par exemple - ceci:

 <div className="contact-card">   <img align="center" src="http://placekitten.com/300/200"/>   <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>   <p>Phone: (212) 555-1234</p>   <p>Email: mr.whiskaz@catnap.meow</p> </div> 

L'application renvoie quatre de ces blocs, chacun pouvant être utilisé pour créer un composant indépendant, mais cette approche ne nous convient pas. Par conséquent, nous allons créer un composant qui deviendra la base de toutes les cartes affichées par l'application. Pour ce faire, créez un nouveau fichier de composant dans le dossier src - ContactCard.js et insérez-y un code qui renvoie le premier élément <div> renvoyé par le composant App , dont le code est donné ci-dessus. Voici le code du composant ContactCard :

 import React from "react" function ContactCard() {   return (       <div className="contact-card">           <img align="center" src="http://placekitten.com/300/200"/>           <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>           <p>Phone: (212) 555-1234</p>           <p>Email: mr.whiskaz@catnap.meow</p>       </div>   ) } export default ContactCard 

Il est clair que si vous créez plusieurs instances de ce composant, elles contiendront toutes les mêmes données, car ces données sont codées en dur dans le code du composant. Et nous aimerions, lors de la création de différentes instances de ce composant, il serait possible de personnaliser les données affichées par celui-ci. Le fait est que le composant pourrait recevoir certaines propriétés, qu'il peut ensuite utiliser.

Nous travaillons avec des composants fonctionnels, qui sont des fonctions JS ordinaires, dans lesquelles, grâce à la bibliothèque React, des constructions spéciales peuvent être utilisées. Comme vous le savez, les fonctions peuvent prendre des arguments, bien qu'elles puissent être utilisées sans arguments. Un ContactCard notre composant ContactCard , sous sa forme actuelle, peut être une fonction si simple que, sans rien accepter, renvoie simplement la somme de deux nombres:

 function addNumbers() {   return 1 + 1 } 

Il peut être utilisé pour trouver la somme des nombres 1 et 1, mais, par exemple, pour ajouter 1 et 2, en utilisant des fonctions qui n'acceptent aucune entrée, il faudrait écrire une nouvelle fonction. Il est assez évident que cette approche entraînera d'énormes inconvénients si vous devez ajouter des nombres différents, donc dans une telle situation, il serait sage de créer une fonction universelle pour ajouter des nombres qui prend deux nombres et renvoie leur somme:

 function addNumbers(a, b) {   return a + b } 

Ce qu'une telle fonction renvoie dépendra des arguments qui lui ont été transmis lors de son appel. En créant des composants React, nous pouvons procéder exactement de la même manière.

Nous importons le composant App.js ContactCard et retournons quatre de ses instances, sans supprimer le code qui forme les cartes sur la page d'application pour l'instant:

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard />           <ContactCard />           <ContactCard />           <ContactCard />           <div className="contact-card">               <img align="center" src="http://placekitten.com/300/200"/>               <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>               <p>Phone: (212) 555-1234</p>               <p>Email: mr.whiskaz@catnap.meow</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/200"/>               <h3><font color="#3AC1EF">▍Fluffykins</font></h3>               <p>Phone: (212) 555-2345</p>               <p>Email: fluff@me.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/300"/>               <h3><font color="#3AC1EF">▍Destroyer</font></h3>               <p>Phone: (212) 555-3456</p>               <p>Email: ofworlds@yahoo.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/200/100"/>               <h3><font color="#3AC1EF">▍Felix</font></h3>               <p>Phone: (212) 555-4567</p>               <p>Email: thecat@hotmail.com</p>           </div>       </div>   ) } export default App 

Maintenant, travaillons sur le code utilisé pour instancier le composant ContactCard . En créant des éléments HTML réguliers, nous pouvons personnaliser leurs attributs qui affectent leur comportement et leur apparence. Les noms de ces attributs sont codés en dur par la norme. Dans le cas des composants, vous pouvez utiliser exactement la même approche, à la seule différence que nous trouvons nous-mêmes les noms d'attributs et décidons nous-mêmes comment ils seront utilisés dans le code des composants.

Chacune des cartes contient quatre informations qui, d'une carte à l'autre, peuvent changer. Il s'agit d'une image d'un chat et de son nom, ainsi que d'un téléphone et d'une adresse e-mail. Laissez le nom du chat être contenu dans la propriété name , l'adresse de l'image dans la propriété imgURL , le téléphone dans la propriété phone et l'adresse e-mail dans la propriété email .

Nous définissons ces propriétés sur les instances des composants ContactCard et, comme nous transférons des données à partir du code qui est déjà dans l' App , nous supprimerons ses fragments correspondants. Par conséquent, le code du composant App ressemblera à ceci:

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard               name="Mr. Whiskerson"               imgUrl="http://placekitten.com/300/200"               phone="(212) 555-1234"               email="mr.whiskaz@catnap.meow"           />                     <ContactCard               name="Fluffykins"               imgUrl="http://placekitten.com/400/200"               phone="(212) 555-2345"               email="fluff@me.com"           />                     <ContactCard               name="Destroyer"               imgUrl="http://placekitten.com/400/300"               phone="(212) 555-3456"               email="ofworlds@yahoo.com"           />                     <ContactCard               name="Felix"               imgUrl="http://placekitten.com/200/100"               phone="(212) 555-4567"               email="thecat@hotmail.com"           />                 </div>   ) } export default App 

Certes, le simple transfert de propriétés à un composant ne suffit pas pour qu'elles puissent y être utilisées. La page, qui sera formée par le composant App ci-dessus, contiendra quatre cartes identiques, dont les données sont définies dans le code du composant ContactCard , qui ne sait pas encore quoi faire des propriétés qui lui sont transférées.


Les données de la carte sont codées en dur dans le code; le composant ne peut pas fonctionner avec les propriétés qui lui sont transmises

Alors maintenant, il est temps de parler de la façon dont le composant ContactCard peut fonctionner avec les propriétés qui lui sont transmises lorsqu'il est instancié.

Nous procédons à la résolution de ce problème en indiquant, lors de la déclaration de la fonction ContactCard , qu'il accepte le paramètre props . Dans ce cas, le code du composant ressemblera à ceci:

 import React from "react" function ContactCard(props) {   return (       <div className="contact-card">           <img align="center" src="http://placekitten.com/300/200"/>           <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>           <p>Phone: (212) 555-1234</p>           <p>Email: mr.whiskaz@catnap.meow</p>       </div>   ) } export default ContactCard 

En fait, ce paramètre peut être appelé comme vous voulez, mais dans React, il est habituel de l'appeler props , et les propriétés dont nous parlons ici sont souvent appelées simplement «accessoires».

Le paramètre props est un objet. Les propriétés de cet objet sont les propriétés transmises au composant lors de son instanciation. C'est-à-dire, par exemple, dans notre objet props , props aura une propriété props.name contenant le nom du chat passé au composant lors de son instanciation. De plus, il aura les propriétés props.imgUrl , props.phone , props.email . Pour vérifier cela, ajoutez la commande console.log(props) au début de la fonction ContactCard .

 import React from "react" function ContactCard(props) {   console.log(props)   return (       <div className="contact-card">           <img align="center" src="http://placekitten.com/300/200"/>           <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>           <p>Phone: (212) 555-1234</p>           <p>Email: mr.whiskaz@catnap.meow</p>       </div>   ) } export default ContactCard 

Cela apportera à la console l'objet d' props reçu par le composant.


Objet d'accessoires de console

Ici, vous pouvez voir la sortie de quatre objets de ContactCard.js . Il y en a tellement parce que nous créons quatre instances du composant ContactCard .

Tout cela nous donne la possibilité d'utiliser dans le code du composant, au lieu de valeurs codées en dur, ce qui lui a été transmis lors de la création de son instance, disponible sous la forme de props objet props .

Et si nous essayons d'utiliser la propriété props.imgUrl ceci:

 <img align="center" src=props.imgUrl/> 

À première vue, une telle construction pourrait fonctionner, mais n'oubliez pas qu'ici, nous devons utiliser une entité à partir de JavaScript dans le code JSX. Nous avons expliqué comment cela se faisait dans l'une des classes précédentes. A savoir, dans notre cas, la propriété de l'objet doit être entourée d'accolades:

 <img align="center" src={props.imgUrl}/> 

Nous traitons les autres éléments retournés par le composant de la même manière, après quoi son code prendra la forme suivante:

 import React from "react" function ContactCard(props) {   return (       <div className="contact-card">           <img align="center" src={props.imgUrl}/>           <h3><font color="#3AC1EF">▍{props.name}</font></h3>           <p>Phone: {props.phone}</p>           <p>Email: {props.email}</p>       </div>   ) } export default ContactCard 

Veuillez noter que dans les champs pour afficher le téléphone et l'adresse e-mail, nous avons laissé les textes Phone: et Email: - Email: avec des espaces à leur suite, car ces textes sont utilisés dans tous les composants. Si vous regardez maintenant la page d'application, vous remarquerez qu'elle contient quatre cartes différentes.


Page formée à l'aide d'un composant universel

Notre composant n'accepte que quatre propriétés. Et si un composant doit passer, par exemple, 50 propriétés? Peut-être que le passage de chacune de ces propriétés sur une ligne distincte, comme cela se fait dans le composant App , sera gênant. Dans de tels cas, vous pouvez utiliser une autre méthode pour transférer des propriétés aux composants. Il consiste dans le fait que lors de la création d'une instance d'un composant, il n'est pas transféré une liste de propriétés, mais un objet avec des propriétés. Voici à quoi cela pourrait ressembler dans l'exemple du premier composant:

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard               contact={{                 name: "Mr. Whiskerson",                 imgUrl: "http://placekitten.com/300/200",                 phone: "(212) 555-1234",                 email: "mr.whiskaz@catnap.meow"               }}           />                     <ContactCard               name="Fluffykins"               imgUrl="http://placekitten.com/400/200"               phone="(212) 555-2345"               email="fluff@me.com"           />                     <ContactCard               name="Destroyer"               imgUrl="http://placekitten.com/400/300"               phone="(212) 555-3456"               email="ofworlds@yahoo.com"           />                     <ContactCard               name="Felix"               imgUrl="http://placekitten.com/200/100"               phone="(212) 555-4567"               email="thecat@hotmail.com"           />                 </div>   ) } export default App 

Cela ne veut pas dire que cette approche a considérablement réduit la quantité de code utilisé pour décrire l'instance de composant. Le fait est que les propriétés transmises au composant sont toujours codées en dur dans le code, bien que nous ne transmettions qu'un seul composant au composant. Les avantages de cette approche peuvent être ressentis dans les situations où les données pour le composant sont obtenues à partir de certaines sources externes. Par exemple, à partir d'un fichier JSON.

Lors de la modification du code du composant App utilisé pour créer la première instance du composant ContactCard , le bon fonctionnement de l'application a été perturbé. Voici à quoi ressemblera sa page.


Dysfonctionnement de l'application

Comment résoudre ce problème? Pour comprendre cela, il sera utile d'analyser ce qui se passe à l'aide de la commande console.log(props) .


Analyse de l'objet accessoires

Comme vous pouvez le voir, l'objet props du premier composant est différent du même objet du deuxième et des composants suivants.

Dans le composant ContactCard nous utilisons l'objet props en supposant qu'il a le name , imgUrl et d'autres propriétés. Ici, le premier composant ne reçoit qu'une seule propriété - contact . Cela conduit au fait que l'objet props n'a qu'une seule propriété - contact , qui est l'objet, et le code du composant ne fournit pas de travail avec une telle structure.

Convertir notre composant en modèle utilisant une seule propriété d'un objet contact contenant d'autres propriétés est assez simple. Pour ce faire, par exemple, pour accéder à la propriété name , il suffit d'utiliser une construction de la forme props.contact.name dans le code du composant. Des conceptions similaires nous permettent de travailler correctement avec d'autres propriétés dont nous avons besoin.

Recyclons le code du composant, en tenant compte du transfert vers lui d'un seul contact propriété-objet contenant d'autres propriétés:

 import React from "react" function ContactCard(props) {   console.log(props)   return (       <div className="contact-card">           <img align="center" src={props.contact.imgUrl}/>           <h3><font color="#3AC1EF">▍{props.contact.name}</font></h3>           <p>Phone: {props.contact.phone}</p>           <p>Email: {props.contact.email}</p>       </div>   ) } export default ContactCard 

Le premier composant devrait maintenant être affiché normalement, mais nous ne le verrons pas à ce stade du projet, car le système nous informera de beaucoup d'erreurs liées au fait que plusieurs instances du composant ContactCard créé dans le composant App ne reçoivent pas la propriété- objet de contact . Lors de l'exécution du code, cette propriété ne sera pas undefined . Par conséquent, une tentative est faite pour faire référence à une certaine propriété de la valeur undefined , ce qui conduit à une erreur. Nous allons résoudre ce problème en traitant le code du composant App responsable de la formation des composants ContactCard :

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard               contact={{                 name: "Mr. Whiskerson",                 imgUrl: "http://placekitten.com/300/200",                 phone: "(212) 555-1234",                 email: "mr.whiskaz@catnap.meow"               }}           />                     <ContactCard               contact={{                 name: "Fluffykins",                 imgUrl: "http://placekitten.com/400/200",                 phone: "(212) 555-2345",                 email: "fluff@me.com"               }}           />                     <ContactCard               contact={{                 name: "Destroyer",                 imgUrl: "http://placekitten.com/400/300",                 phone: "(212) 555-3456",                 email: "ofworlds@yahoo.com"               }}           />                     <ContactCard               contact={{                 name: "Felix",                 imgUrl: "http://placekitten.com/200/100",                 phone: "(212) 555-4567",                 email: "thecat@hotmail.com"               }}           />                 </div>   ) } export default App 

Maintenant, la page d'application sera la même qu'avant.

Comme d'habitude, il est recommandé d'expérimenter les concepts que vous avez appris aujourd'hui afin de mieux les comprendre. Par exemple, vous pouvez travailler avec le code, ajouter de nouvelles propriétés transmises au composant et essayer de les utiliser dans le composant.

Résumé


Aujourd'hui, nous avons introduit le concept de propriétés pouvant être transmises aux composants React afin de contrôler leur comportement et leur apparence. Ces propriétés ressemblent aux attributs des éléments HTML, mais, en utilisant les propriétés des composants, le programmeur décide indépendamment de leur signification et de ce qu'il faut en faire exactement dans le composant. La prochaine fois, vous aurez une leçon pratique sur l'utilisation des propriétés et du style des composants.

Chers lecteurs! Comment avez-vous expérimenté le code de l'exemple d'aujourd'hui afin de mieux comprendre les propriétés des composants React?

Source: https://habr.com/ru/post/fr436032/


All Articles