Im heutigen Teil der Übersetzung des React-Schulungskurses sind Sie eingeladen, eine Formularaufgabe zu erledigen.

→
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 KomponentenlebenszyklusTeil 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: KursprojektLektion 43. Workshop. Mit Formularen arbeiten
→
Original»Job
In dieser praktischen Lektion werden Sie aufgefordert, den Code der
App
Komponente
App.js
, der sich in der Datei
App.js
des von create-react-app erstellten Standardprojekts befindet. Hier ist der Code:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } render() { return ( <main> <form> <input placeholder="First Name" /><br /> <input placeholder="Last Name" /><br /> <input placeholder="Age" /><br /> {/* */} <br /> {/* */} <br /> {/* */} <br /> <button>Submit</button> </form> <hr /> <h2><font color="#3AC1EF">Entered information:</font></h2> <p>Your name: {/* */}</p> <p>Your age: {/* */}</p> <p>Your gender: {/* */}</p> <p>Your destination: {/* */}</p> <p> Your dietary restrictions: {/* */} </p> </main> ) } } export default App
Im Allgemeinen müssen Sie sicherstellen, dass die Daten, die der Benutzer während der Arbeit mit den Formularsteuerelementen eingibt, sofort im Text unter diesem Formular angezeigt werden. Nutzen Sie die
verwaltete Komponententechnologie , wenn Sie die Aufgabe erledigen. Es ist zu beachten, dass die Ihnen angebotene Aufgabe eine angepasste Version
dieser Aufgabe ist, sodass Sie sie sich ansehen können, um die Funktionen der Steuerelemente, die Sie erstellen und konfigurieren sollen, besser zu verstehen.
Hier ist, was die Komponente jetzt auf dem Bildschirm anzeigt.
Anwendung im Browser▍Lösung
Sie können sich der Lösung des Ihnen vorgeschlagenen Problems von verschiedenen Seiten nähern. Wir beginnen damit, alles, was wir brauchen, in den Zustand zu versetzen, wonach wir die Kontrollen und andere Mechanismen der Komponente einrichten.
Im Moment sieht der Status der Komponente wie unten gezeigt aus.
this.state = { firstName: "", lastName: "", age: 0, gender: "", destination: "", dietaryRestrictions: [] }
Es sollte bedacht werden, dass sich bei der Arbeit an einem Programm möglicherweise herausstellt, dass es beispielsweise bequemer ist, einen Zustand anders zu initialisieren. Wenn wir auf etwas Ähnliches stoßen, ändern wir den Statusinitialisierungscode. Insbesondere können jetzt einige Zweifel durch die in die Eigenschaft
age
geschriebene Zahl 0 verursacht werden, in der das vom Benutzer eingegebene Alter gespeichert werden soll. Möglicherweise muss das Flag-Datenspeichersystem, das jetzt durch die Eigenschaft
dietaryRestrictions
, die durch ein leeres Array initialisiert wird, etwas anderes tun.
Lassen Sie uns nun nach der Initialisierung des Status die Einstellungen vornehmen. Da der Code bereits eine Beschreibung der Eingabefelder enthält, beginnen wir mit ihnen.
Diese Steuerelemente müssen benannt werden, indem ihre Namensattribute so festgelegt werden, dass sie mit den Namen der Statuseigenschaften übereinstimmen, in denen die in diese Felder eingegebenen Daten gespeichert werden. Sie sollten ein
value
, dessen Wert basierend auf den im Status gespeicherten Daten bestimmt wird. Wenn Sie Daten in jedes dieser Felder
onChange
, müssen Sie die eingegebenen Daten an die Komponente übergeben, was dazu führt, dass sie über einen
onChange
Ereignishandler verfügen
onChange
. All diese Überlegungen führen dazu, dass die Beschreibung der Felder nun so aussieht:
<input name="firstName" value={this.state.firstName} onChange={this.handleChange} placeholder="First Name" /> <br /> <input name="lastName" value={this.state.lastName} onChange={this.handleChange} placeholder="Last Name" /> <br /> <input name="age" value={this.state.age} onChange={this.handleChange} placeholder="Age" />
this.handleChange
ist als Methode zur Verarbeitung der
onChange
Ereignisse dieser Felder noch nicht vorhanden. Erstellen Sie diese Methode:
handleChange(event) { const {name, value} = event.target this.setState({ [name]: value }) }
Hier extrahieren wir die
name
und Werteigenschaften aus dem
event.target
Objekt und verwenden sie dann, um die entsprechende
event.target
. Im Moment wird ein solcher universeller Ereignishandlercode zu uns passen, aber später, wenn wir mit Flags arbeiten, werden wir Änderungen daran vornehmen.
Vergessen Sie nicht, dass
this
Bindung im Komponentenkonstruktor ausgeführt wird:
this.handleChange = this.handleChange.bind(this)
Um eine Ausgabe am Ende der Seite der Daten zu erreichen, die in die Felder
firstName
,
secondName
und
age
firstName
,
secondName
wir mit den entsprechenden
<p>
-Elementen und bringen sie in die folgende Form:
<p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p>
Schauen wir uns jetzt an, was wir haben.
Anwendung im BrowserWie Sie sehen können, wird im Feld zur Eingabe des Alters kein Hinweis angezeigt. Stattdessen wird angezeigt, was in der Eigenschaft state of
age
ist, dh 0. Wir benötigen einen Hinweis im leeren Feld. Versuchen wir, den Wert des
age
im Status durch
null
zu ersetzen. Danach stellt sich heraus, dass das Formular so aussieht, wie es sollte, aber in der Konsole wird die folgende Warnung bezüglich des Altersfelds angezeigt:
Warning: `value` prop on `input` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components
Infolgedessen müssen wir den Wert der Eigenschaft
age
state durch eine leere Zeichenfolge ersetzen und den Statusinitialisierungscode in die folgende Form bringen:
this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", dietaryRestrictions: [] }
Probieren Sie jetzt das Formular aus. Unmittelbar nach der Eröffnung sieht es genauso aus wie zu Beginn der Arbeit, dh die Eingabeaufforderung kehrt zum
age
zurück. Beim Ausfüllen der Felder werden die eingegebenen Daten unten auf der Seite angezeigt.
Anwendung im BrowserWie Sie sehen, funktioniert in dieser Phase der Arbeit alles wie erwartet.
Jetzt werden wir uns mit neuen Elementen beschäftigen. Der nächste Schritt bei der Bearbeitung des Formulars ist das Hinzufügen von Schaltern.
Wickeln Sie die Schalter in das
<label>
, damit wir nicht nur den Schalter signieren, sondern auch sicherstellen können, dass das Klicken auf diese Signatur, dh auf das übergeordnete Element, zur Auswahl führt.
Wenn Sie mit Switches arbeiten, sollten Sie bedenken, dass es sich um eine Kombination von Flags mit dem
checked
Attribut und Textfeldern mit dem
checked
. Die Switches bilden eine Gruppe, in der jedem der Switches derselbe Name zugewiesen wird, und die
checked
Eigenschaft der Switches wird gemäß einer Bedingung festgelegt, die so konfiguriert ist, dass es unmöglich ist, mehr als einen Switch einzuschalten, der Teil derselben Gruppe ist.
onChange
als Ereignishandler für die
onChange
Switches fest.
Infolgedessen sieht der Schalterbeschreibungscode folgendermaßen aus:
<label> <input type="radio" name="gender" value="male" checked={this.state.gender === "male"} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.gender === "female"} onChange={this.handleChange} /> Female </label>
Jetzt verarbeiten wir das entsprechende
<p>
-Element am Ende der Seite wie folgt:
<p>Your gender: {this.state.gender}</p>
Danach kann das Formular getestet werden. Unmittelbar nach dem Start werden beide Schalter nicht ausgewählt, da ein Status in einem Wert gespeichert ist, bei dem keine der beim Festlegen ihrer
checked
Eigenschaft durchgeführten
checked
true
. Nachdem Sie auf einen von ihnen geklickt haben, fällt der entsprechende Wert in den Status (gespeichert im Wertattribut des Schalters), der Schalter wird ausgewählt und der entsprechende Text wird am unteren Rand des Formulars angezeigt.
Anwendung im BrowserLassen Sie uns nun am Kombinationsfeld arbeiten. Sein Werkstück sieht so aus:
<select> <option></option> <option></option> <option></option> <option></option> </select>
Dieser Code zeigt, dass wir ein Kombinationsfeld mit vier Elementen beschreiben möchten.
Das
<select>
-Tag und seine
<option>
-Tags haben ein Wertattribut. Diese Attribute haben jedoch unterschiedliche Bedeutungen. Der dem
<option>
-Element zugewiesene
value
gibt an, wie die entsprechende Statuseigenschaft aussehen soll, wenn dieses Element ausgewählt wird. Dies sind die Zeilen, die in der Dropdown-Liste enthalten sein sollten. In unserem Fall sind dies bestimmte Ziele, beispielsweise Länder. Schreiben wir ihre Namen mit einem kleinen Buchstaben, damit ihr Aussehen den Werten der Werteigenschaften anderer Elemente im Code entspricht. Danach sieht der Code für das Kombinationsfeld folgendermaßen aus:
<select value=> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
Wenn wir über das
value
Attribut des
<select>
sprechen, wird hier kein fest codierter Wert angezeigt, sondern ein Link zur entsprechenden state-Eigenschaft:
<select value={this.state.destination}> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
Weisen Sie dem Feld andere Attribute zu. Insbesondere der Name, der dem Namen der Eigenschaft im Status entspricht, und der
onChange
Ereignishandler
this.handleChange
.
<select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
Jetzt konfigurieren wir die Beschreibung des
<p>
-Elements, das anzeigt, was im
destination
ausgewählt
destination
:
<p>Your destination: {this.state.destination}</p>
Wenn Sie sich jetzt die Seite im Browser ansehen, können Sie sehen, dass das erste Element der Liste automatisch im Feld ausgewählt wird. Dies führt jedoch offensichtlich nicht zu einer Aktualisierung des Status, da nach dem Doppelpunkt in der Zeile
Your destination:
nichts angezeigt wird.
Anwendung im BrowserDamit der deutsche Wert in den Status fällt, müssen Sie das Kombinationsfeld öffnen und zuerst etwas anderes und dann
Germany
auswählen.
Um diese Funktion von Listenfeldern in ihren Listen als erstes Element zu berücksichtigen, setzen sie häufig so etwas wie ein Element mit einem leeren Wert und einem Text wie "
-- Please Choose a destination --
. In unserem Fall könnte es so aussehen:
<select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="">-- Please Choose a destination --</option> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
Wir werden uns auf diese Option zum Einstellen des Kombinationsfelds konzentrieren.
Lassen Sie uns nun den vielleicht schwierigsten Teil unserer Aufgabe behandeln, der mit Flaggen verbunden ist. Hier ist zu
dietaryRestrictions
dass die staatliche Eigenschaft
dietaryRestrictions
, die für die Arbeit mit Flags verwendet werden soll, mit einem leeren Array initialisiert wurde. Wenn es um die Arbeit mit Steuerelementen geht, besteht das Gefühl, dass es besser ist, dieses Feld als Objekt darzustellen. Daher ist es bequemer, mit Entitäten zu arbeiten, die einzelne Flags in Form von Eigenschaften dieses Objekts mit Anzeigenamen und nicht in Form von Array-Elementen darstellen. Die Eigenschaften des Objekts, die jetzt durch die
dietaryRestrictions
state dargestellt werden, enthalten boolesche Werte, die angeben, ob das entsprechende Kontrollkästchen
dietaryRestrictions
(
false
) oder aktiviert (
true
) ist. Der Statusinitialisierungscode sieht nun folgendermaßen aus:
this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", dietaryRestrictions: { isVegan: false, isKosher: false, isLactoseFree: false } }
Wie Sie sehen können, planen wir die Erstellung von drei Flags. Alle werden unmittelbar nach dem Laden der Seite zurückgesetzt.
Wir beschreiben die Flags in dem von der Komponente zurückgegebenen Code, wickeln sie in
<label>
-Tags ein und legen ihre Attribute fest. So wird ihr Code aussehen:
<label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isLactoseFree} /> Lactose Free? </label>
Die Namen der verwendeten Flags sind Eigenschaftsnamen des
dietaryRestrictions
Objekts, und die Werte ihrer
checked
Attribute sind Konstruktionen der Form
this.state.dietaryRestrictions.isSomething
.
Bitte beachten Sie, dass der bereits vorhandene
onChange
zwar als
this.handleChange
Ereignishandler angezeigt wird, wir jedoch einige Änderungen am Programm vornehmen müssen, um sicherzustellen, dass das Programm ordnungsgemäß funktioniert.
Schauen Sie sich die Anwendung an.
Anwendung im BrowserWie Sie sehen können, werden die Flags auf der Seite angezeigt, aber die Komponente enthält noch nicht alle Mechanismen, die für den ordnungsgemäßen Betrieb erforderlich sind. Beschäftigen wir uns mit dem Event-Handler.
event.target
mit Kontrollkästchen arbeiten zu können, müssen wir
event.target
aus dem Objekt extrahieren, zusätzlich zu den bereits extrahierten, dem
type
und den
checked
Eigenschaften. Das erste wird benötigt, um den Typ des Elements zu überprüfen (die Flags sind vom Typ, der durch die
checkbox
wird), das zweite, um herauszufinden, ob das Kontrollkästchen aktiviert oder deaktiviert ist. Wenn sich herausstellt, dass der Handler aufgerufen wurde, nachdem der Benutzer mit dem Flag interagiert hat, verwenden wir ein spezielles Statuseinstellungsverfahren. Wir werden die Ereignisse anderer Steuerelemente auf die gleiche Weise wie zuvor behandeln.
Bei der Aktualisierung eines Status sollte berücksichtigt werden, dass React ein ziemlich intelligentes System ist, das, wenn nur ein Teil des Status aktualisiert wird, automatisch im neuen Status kombiniert, was unverändert geblieben ist, mit dem, was sich geändert hat. Man kann jedoch nicht sicher sein, dass die Arbeit mit den Eigenschaften von Objekten, die die Werte von Zustandseigenschaften sind, auf die gleiche Weise ausgeführt wird. Wir werden dies überprüfen, indem wir den
handleChange
Code in das folgende Formular bringen. Hier gehen wir von der Annahme aus, dass die Eigenschaften des Objekts
dietaryRestrictions
einzeln geändert werden können:
handleChange(event) { const {name, value, type, checked} = event.target type === "checkbox" ? this.setState({ dietaryRestrictions: { [name]: checked } }) : this.setState({ [name]: value }) }
Wenn Sie die Anwendungsseite in einem Browser öffnen, sieht sofort nach dem Herunterladen alles gut aus. Wenn Sie beispielsweise versuchen, einen Namen in das Feld
First Name
einzugeben, funktioniert alles wie zuvor. Wenn Sie jedoch versuchen, eines der Kontrollkästchen zu aktivieren, wird die folgende Warnung ausgegeben ::
Warnung: Eine Komponente ändert ein Kontrollkästchen für eine kontrollierte Eingabe vom Typ so, dass sie nicht mehr gesteuert wird. Eingabeelemente sollten nicht von gesteuert zu unkontrolliert (oder umgekehrt) wechseln. Entscheiden Sie sich für die Lebensdauer der Komponente zwischen der Verwendung eines gesteuerten oder unkontrollierten Eingabeelements. Weitere Informationen: fb.me/react-controlled-components
Um den Inhalt des
dietaryRestrictions
Objekts korrekt zu aktualisieren, können Sie mit dem Funktionsformular
setState
selbst eine neue Version des Status erstellen. Wenn wir eine große Anzahl von Flags verwalten müssten, hätten wir dies wahrscheinlich getan. Aber hier werden wir es anders machen. Wir werden nämlich die Eigenschaften der
dietaryRestrictions
von
dietaryRestrictions
dieses Objekt
dietaryRestrictions
:
this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", isVegan: false, isKosher: false, isLactoseFree: false }
Jetzt ändern wir die Einstellungen für die Attribute der Flags, um
dietaryRestrictions
:
<label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.isLactoseFree} /> Lactose Free? </label>
Bearbeiten Sie abschließend den Code des Elements, in dem Informationen zu den vom Benutzer angegebenen Ernährungseinschränkungen angezeigt werden:
<p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p>
Danach überprüfen wir den Zustand der Anwendung.
Anwendung im BrowserWie Sie sehen, funktioniert alles wie erwartet.
Hier ist der vollständige Code der
App
Komponente:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", isVegan: false, isKosher: false, isLactoseFree: false } this.handleChange = this.handleChange.bind(this) } handleChange(event) { const {name, value, type, checked} = event.target type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value }) } render() { return ( <main> <form> <input name="firstName" value={this.state.firstName} onChange={this.handleChange} placeholder="First Name" /> <br /> <input name="lastName" value={this.state.lastName} onChange={this.handleChange} placeholder="Last Name" /> <br /> <input name="age" value={this.state.age} onChange={this.handleChange} placeholder="Age" /> <br /> <label> <input type="radio" name="gender" value="male" checked={this.state.gender === "male"} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.gender === "female"} onChange={this.handleChange} /> Female </label> <br /> <select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="">-- Please Choose a destination --</option> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select> <br /> <label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.isLactoseFree} /> Lactose Free? </label> <br /> <button>Submit</button> </form> <hr /> <h2><font color="#3AC1EF">Entered information:</font></h2> <p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p> <p>Your gender: {this.state.gender}</p> <p>Your destination: {this.state.destination}</p> <p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p> </main> ) } } export default App
Zusammenfassung
Heute haben Sie die praktische Arbeit an den Formularen abgeschlossen. Dann haben Sie wiederholt, was Sie in früheren Kursen gelernt haben, und wir hoffen, Sie haben etwas Neues gelernt. Nächstes Mal werden wir über die Architektur von React-Anwendungen sprechen.
Liebe Leser! Sag mir, war es schwierig, diese praktische Arbeit abzuschließen?
