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?
