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.

→
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 composantsPartie 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 coursLeçon 19. Propriétés des composants dans React
→
OriginalCré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 navigateurAprè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 transmisesAlors 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 consoleIci, 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 universelNotre 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'applicationComment 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 accessoiresComme 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?