React Tutorial Teil 9: Komponenteneigenschaften

Im heutigen Teil der Übersetzung des React-Tutorials werden wir uns mit Komponenteneigenschaften befassen. Dies ist eines der wichtigsten Konzepte in dieser Bibliothek.

Bild

Teil 1: Kursübersicht, Gründe für die Beliebtheit von React, ReactDOM und JSX
Teil 2: Funktionskomponenten
Teil 3: Komponentendateien, Projektstruktur
Teil 4: übergeordnete und untergeordnete Komponenten
Teil 5: Beginn der Arbeit an einer TODO-Anwendung, Grundlagen des Stylings
Teil 6: Über einige Funktionen des Kurses, JSX und JavaScript
Teil 7: Inline-Stile
Teil 8: Fortsetzung der Arbeit an der TODO-Anwendung, Vertrautheit mit den Eigenschaften von Komponenten
Teil 9: Komponenteneigenschaften
Teil 10: Workshop zum Arbeiten mit Komponenteneigenschaften und Styling
Teil 11: Dynamische Markup-Generierung und Map-Arrays-Methode
Teil 12: Workshop, dritte Phase der Arbeit an einer TODO-Anwendung
Teil 13: Klassenbasierte Komponenten
Teil 14: Workshop zu klassenbasierten Komponenten, Komponentenstatus
Teil 15: Komponentengesundheitsworkshops
Teil 16: Die vierte Phase der Arbeit an einer TODO-Anwendung, die Ereignisbehandlung
Teil 17: Fünfte Phase der Arbeit an einer TODO-Anwendung, Änderung des Status von Komponenten
Teil 18: Die sechste Phase der Arbeit an einer TODO-Anwendung
Teil 19: Methoden des Komponentenlebenszyklus
Teil 20: Die erste Lektion in bedingtem Rendern
Teil 21: Zweite Lektion und Workshop zum bedingten Rendern
Teil 22: Die siebte Phase der Arbeit an einer TODO-Anwendung, bei der Daten aus externen Quellen heruntergeladen werden
Teil 23: Erste Lektion zum Arbeiten mit Formularen
Teil 24: Lektion der zweiten Form
Teil 25: Workshop zum Arbeiten mit Formularen
Teil 26: Anwendungsarchitektur, Container- / Komponentenmuster
Teil 27: Kursprojekt

Lektion 19. Komponenteneigenschaften in React


Original

Erstellen Sie ein neues Projekt mit create-react-app und ändern Sie den Code mehrerer Standarddateien aus dem Ordner src .

Hier ist der Code für die Datei index.js :

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

Hier sind die Stile, die in der Datei index.css werden:

 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; } 

Hier ist der Code in der Datei 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 

So sieht diese App in einem Browser aus.


Anwendungsseite im Browser

Nach der Analyse des Codes und des Erscheinungsbilds der Anwendung können wir den Schluss ziehen, dass es hilfreich wäre, spezielle Komponenten zu verwenden, um Karten mit Informationen über Tiere anzuzeigen. Diese Elemente werden nun mithilfe der App Komponente gebildet. In Anbetracht dessen, worüber wir in früheren Klassen gesprochen haben, können Sie noch weiter gehen - denken Sie an eine universelle Komponente, die angepasst werden kann, indem Attribute oder Eigenschaften an sie übergeben werden.

In unserer Anwendung gibt es Karten mit Bildern von Katzen, ihren Namen und Kontaktinformationen ihrer Besitzer (oder vielleicht ihrer selbst) - ein Telefon und eine E-Mail-Adresse. Um eine Komponente zu erstellen, die später als Grundlage für alle diese Karten dient, können Sie eines der von der App Komponente zurückgegebenen Markup-Fragmente verwenden. Zum Beispiel - dies:

 <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> 

App gibt vier solcher Blöcke zurück, von denen jeder zum Erstellen einer unabhängigen Komponente verwendet werden kann, aber dieser Ansatz passt nicht zu uns. Daher erstellen wir eine Komponente, die die Grundlage für alle von der Anwendung angezeigten Karten bildet. Erstellen Sie dazu eine neue Komponentendatei im Ordner src - ContactCard.js und ContactCard.js Sie einen Code ein, der das erste von der App Komponente zurückgegebene <div> -Element zurückgibt, dessen Code oben angegeben ist. Hier ist der Code für die ContactCard Komponente:

 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 

Es ist klar, dass, wenn Sie mehrere Instanzen dieser Komponente erstellen, alle dieselben Daten enthalten, da diese Daten im Komponentencode fest codiert sind. Und wir möchten, dass beim Erstellen verschiedener Instanzen dieser Komponente die von ihr angezeigten Daten angepasst werden können. Der Punkt ist, dass der Komponente bestimmte Eigenschaften übergeben werden könnten, die er dann verwenden kann.

Wir arbeiten mit Funktionskomponenten, bei denen es sich um gewöhnliche JS-Funktionen handelt, bei denen dank der React-Bibliothek spezielle Konstruktionen verwendet werden können. Wie Sie wissen, können Funktionen Argumente annehmen, obwohl sie ohne Argumente verwendet werden können. Ein ContactCard unserer ContactCard Komponente in der Form, in der sie jetzt existiert, kann eine so einfache Funktion sein, dass, ohne etwas zu akzeptieren, einfach die Summe zweier Zahlen zurückgegeben wird:

 function addNumbers() {   return 1 + 1 } 

Es kann verwendet werden, um die Summe der Zahlen 1 und 1 herauszufinden, aber um beispielsweise 1 und 2 zu addieren und Funktionen zu verwenden, die keine Eingabe akzeptieren, müssten wir eine neue Funktion schreiben. Es ist ziemlich offensichtlich, dass dieser Ansatz zu großen Unannehmlichkeiten führt, wenn Sie verschiedene Zahlen hinzufügen müssen. In einer solchen Situation ist es daher ratsam, eine universelle Funktion zum Hinzufügen von Zahlen zu erstellen, die zwei Zahlen akzeptiert und deren Summe zurückgibt:

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

Was eine solche Funktion zurückgibt, hängt davon ab, welche Argumente beim Aufruf an sie übergeben wurden. Durch das Erstellen von React-Komponenten können wir genauso vorgehen.

Wir importieren die App.js Komponente ContactCard und geben vier ihrer Instanzen zurück, ohne den Code zu löschen, der die Karten auf der Anwendungsseite bildet:

 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 

Lassen Sie uns nun an dem Code arbeiten, der zum Instanziieren der ContactCard Komponente verwendet wird. Durch das Erstellen regulärer HTML-Elemente können wir deren Attribute anpassen, die sich auf ihr Verhalten und Erscheinungsbild auswirken. Die Namen dieser Attribute sind vom Standard fest codiert. Bei Komponenten können Sie genau den gleichen Ansatz verwenden. Der einzige Unterschied besteht darin, dass wir die Attributnamen selbst erstellen und selbst entscheiden, wie sie im Komponentencode verwendet werden.

Jede der Karten enthält vier Informationen, die sich von Karte zu Karte ändern können. Dies ist ein Bild einer Katze und ihres Namens sowie eine Telefon- und E-Mail-Adresse. Lassen Sie den Katzennamen in der Eigenschaft name , die imgURL in der Eigenschaft imgURL , das Telefon in der Eigenschaft phone und die E-Mail-Adresse in der Eigenschaft email .

Wir setzen diese Eigenschaften auf Instanzen von ContactCard Komponenten und löschen beim Übertragen von Daten aus dem Code, der bereits in der App , die entsprechenden Fragmente. Infolgedessen sieht der Code der App Komponente folgendermaßen aus:

 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 

Die bloße Übertragung von Eigenschaften auf eine Komponente reicht zwar nicht aus, um sie darin zu verwenden. Die Seite, die von der obigen App Komponente gebildet wird, enthält vier identische Karten, deren Daten im Code der ContactCard Komponente festgelegt sind, die noch nicht weiß, was mit den darauf übertragenen Eigenschaften zu tun ist.


Kartendaten sind im Code fest codiert, die Komponente kann nicht mit den an sie übergebenen Eigenschaften arbeiten

Jetzt ist es an der Zeit, darüber zu sprechen, wie die ContactCard Komponente mit den Eigenschaften arbeiten kann, die bei der Instanziierung an sie übergeben werden.

Wir lösen dieses Problem, indem wir beim Deklarieren der ContactCard Funktion angeben, dass sie den props akzeptiert. In diesem Fall sieht der Komponentencode folgendermaßen aus:

 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 

Tatsächlich kann dieser Parameter beliebig genannt werden, aber in React ist es üblich, ihn als props , und die Eigenschaften, über die wir hier sprechen, werden oft einfach als „Requisiten“ bezeichnet.

Der Parameter props ist ein Objekt. Die Eigenschaften dieses Objekts sind die Eigenschaften, die bei der Instanziierung an die Komponente übergeben werden. Das heißt, in unserem props es beispielsweise eine Eigenschaft props.name die den Namen der Katze enthält, die an die Komponente übergeben wurde, als sie instanziiert wurde. Darüber hinaus verfügt es über die Eigenschaften props.imgUrl , props.phone , props.email . Um dies zu überprüfen, fügen Sie den console.log(props) am Anfang der ContactCard Funktion hinzu.

 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 

Dadurch wird das von der Komponente empfangene props zur Konsole gebracht.


Konsolen-Requisitenobjekt

Hier sehen Sie die Ausgabe von vier Objekten aus ContactCard.js . Es gibt so viele davon, weil wir vier Instanzen der ContactCard Komponente erstellen.

All dies gibt uns die Möglichkeit, im Komponentencode anstelle von fest codierten Werten zu verwenden, was beim Erstellen der Instanz an ihn übergeben wurde, und zwar in Form von props .

Was ist, wenn wir versuchen, die Eigenschaft props.imgUrl zu verwenden:

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

Auf den ersten Blick mag eine solche Konstruktion funktionieren, aber denken Sie daran, dass wir hier eine Entität aus JavaScript in JSX-Code verwenden müssen. Wir haben darüber gesprochen, wie dies in einer der vorherigen Klassen gemacht wird. In unserem Fall muss die Eigenschaft des Objekts nämlich in geschweiften Klammern stehen:

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

Wir verarbeiten die anderen von der Komponente zurückgegebenen Elemente auf die gleiche Weise. Danach hat der Code die folgende Form:

 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 

Bitte beachten Sie, dass in den Feldern zur Anzeige der Telefon- und E-Mail-Adresse die Texte Phone: und Email: mit Leerzeichen gefolgt sind, da diese Texte in allen Komponenten verwendet werden. Wenn Sie sich jetzt die Anwendungsseite ansehen, werden Sie feststellen, dass sie vier verschiedene Karten enthält.


Seite gebildet mit einer universellen Komponente

Unsere Komponente akzeptiert nur vier Eigenschaften. Was ist, wenn eine Komponente beispielsweise 50 Eigenschaften übergeben muss? Möglicherweise ist es unpraktisch, jede dieser Eigenschaften als separate Zeile zu übergeben, wie dies in der App Komponente der Fall ist. In solchen Fällen können Sie Eigenschaften auf andere Weise auf Komponenten übertragen. Es besteht darin, dass beim Erstellen einer Instanz einer Komponente keine Liste von Eigenschaften übertragen wird, sondern ein Objekt mit Eigenschaften. So könnte es am Beispiel der ersten Komponente aussehen:

 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 

Dies bedeutet nicht, dass dieser Ansatz die Menge an Code, die zur Beschreibung der Komponenteninstanz verwendet wird, erheblich reduziert hat. Tatsache ist, dass die an die Komponente übergebenen Eigenschaften im Code immer noch fest codiert sind, obwohl wir nur eine Komponente an die Komponente übergeben. Die Vorteile dieses Ansatzes sind in Situationen zu spüren, in denen die Daten für die Komponente aus einigen externen Quellen stammen. Zum Beispiel aus einer JSON-Datei.

Während der Änderung des Codes der App Komponente, mit der die erste Instanz der ContactCard Komponente erstellt wurde, wurde der ordnungsgemäße Betrieb der Anwendung unterbrochen. So wird seine Seite jetzt aussehen.


Fehlfunktion der Anwendung

Wie kann das behoben werden? Um dies zu verstehen, ist es hilfreich, mit dem console.log(props) zu analysieren, was passiert.


Analyse des Requisitenobjekts

Wie Sie sehen können, unterscheidet sich das props der ersten Komponente vom gleichen Objekt der zweiten und nächsten Komponente.

In der ContactCard Komponente verwenden wir das props unter der Annahme, dass es den name , imgUrl und andere Eigenschaften hat. Hier erhält die erste Komponente nur eine Eigenschaft - contact . Dies führt dazu, dass das props nur eine Eigenschaft hat - contact , nämlich das Objekt, und der Komponentencode keine Arbeit mit einer solchen Struktur bietet.

Das Konvertieren unserer Komponente in das Modell, nur eine Eigenschaft eines contact , das andere Eigenschaften enthält, ist recht einfach. Um beispielsweise auf die Eigenschaft name zuzugreifen, reicht es aus, im Komponentencode eine Konstruktion der Form props.contact.name zu verwenden. Ähnliche Designs ermöglichen es uns, mit anderen Eigenschaften, die wir benötigen, richtig zu arbeiten.

Lassen Sie uns den Komponentencode recyceln und dabei die Übertragung eines einzelnen Objekt-Objekt- contact berücksichtigen, der andere Eigenschaften enthält:

 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 

Die erste Komponente sollte jetzt normal angezeigt werden, dies wird jedoch in dieser Phase des Projekts nicht angezeigt, da das System uns über viele Fehler informiert, die darauf zurückzuführen sind, dass mehrere in der App Komponente erstellte Instanzen der ContactCard Komponente die Eigenschaft nicht erhalten. contact . Bei der Ausführung des Codes ist diese Eigenschaft undefined . Infolgedessen wird versucht, auf eine bestimmte Eigenschaft des undefined Werts zu verweisen, was zu einem Fehler führt. Wir werden dies beheben, indem wir den Code der App Komponente verarbeiten, die für die Bildung von ContactCard Komponenten verantwortlich ist:

 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 

Jetzt sieht die Anwendungsseite genauso aus wie zuvor.

Wie üblich wird empfohlen, mit den heute erlernten Konzepten zu experimentieren, um sie besser zu verstehen. Sie können beispielsweise mit dem Code arbeiten, neue Eigenschaften hinzufügen, die an die Komponente übergeben werden, und versuchen, sie in der Komponente zu verwenden.

Zusammenfassung


Heute haben wir das Konzept von Eigenschaften eingeführt, die an React-Komponenten übergeben werden können, um deren Verhalten und Erscheinungsbild zu steuern. Diese Eigenschaften ähneln den Attributen von HTML-Elementen, aber anhand der Eigenschaften in den Komponenten entscheidet der Programmierer unabhängig, welche Bedeutung sie haben und was genau mit ihnen in der Komponente zu tun ist. Das nächste Mal erhalten Sie eine praktische Lektion zum Arbeiten mit Komponenteneigenschaften und zum Styling.

Liebe Leser! Wie haben Sie mit dem Code für das heutige Beispiel experimentiert, um die Eigenschaften von React-Komponenten besser zu verstehen?

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


All Articles