In diesem Teil der Ăśbersetzung des React-Schulungskurses werden Sie aufgefordert, einen Meme-Generator zu erstellen.

→ 
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 45. Kursprojekt. Meme Generator
→ 
OriginalAlso kamen wir zum Kursprojekt. Erstellen wir eine Anwendung, die Memes generiert. Beginnen wir mit dem Standardprojekt create-react-app, das mit diesem Befehl erstellt wurde:
npx create-react-app meme-generator 
Hier finden Sie Informationen zu den Verwendungsmöglichkeiten.
Während der Arbeit an diesem Projekt werden Sie gebeten, einige seiner Teile selbst zu implementieren und dann die Erläuterungen dazu zu lesen. Das Standardprojekt verfügt bereits über Boilerplate-Code, insbesondere in den 
App.js index.js und 
App.js Sie können diesen Code vollständig entfernen und versuchen, ihn selbst zu schreiben, um sich in der Implementierung der Standardmechanismen von React-Anwendungen zu testen.
In diesem Projekt sind Sie eingeladen, die folgenden Stile zu verwenden:
 * {   box-sizing: border-box; } body {   margin: 0;   background-color: whitesmoke; } header {   height: 100px;   display: flex;   align-items: center;   background: #6441A5;     background: -webkit-linear-gradient(to right, #2a0845, #6441A5);     background: linear-gradient(to right, #2a0845, #6441A5);  } header > img {   height: 80%;   margin-left: 10%; } header > p {   font-family: VT323, monospace;   color: whitesmoke;   font-size: 50px;   margin-left: 60px; } .meme {   position: relative;   width: 90%;   margin: auto; } .meme > img {   width: 100%; } .meme > h2 {   position: absolute;   width: 80%;   text-align: center;   left: 50%;   transform: translateX(-50%);   margin: 15px 0;   padding: 0 5px;   font-family: impact, sans-serif;   font-size: 2em;   text-transform: uppercase;   color: white;   letter-spacing: 1px;   text-shadow:       2px 2px 0 #000,       -2px -2px 0 #000,       2px -2px 0 #000,       -2px 2px 0 #000,       0 2px 0 #000,       2px 0 0 #000,       0 -2px 0 #000,       -2px 0 0 #000,       2px 2px 5px #000; } .meme > .bottom {   bottom: 0; } .meme > .top {   top: 0; } .meme-form {   width: 90%;   margin: 20px auto;   display: flex;   justify-content: space-between; } .meme-form > input {   width: 45%;   height: 40px; } .meme-form > button {   border: none;   font-family: VT323, monospace;   font-size: 25px;   letter-spacing: 1.5px;   color: white;   background: #6441A5; } .meme-form > input::-webkit-input-placeholder {  font-family: VT323, monospace; font-size: 25px; text-align: cen } .meme-form > input::-moz-placeholder {  font-family: VT323, monospace; font-size: 25px; text-align: cen } .meme-form > input:-ms-input-placeholder {  font-family: VT323, monospace; font-size: 25px; text-align: cen } .meme-form > input:-moz-placeholder {  font-family: VT323, monospace; font-size: 25px; text-align: cen } 
Diese Stile können in der Datei 
index.css enthalten sein, die sich bereits im Projekt befindet, und in der Datei 
index.js enthalten sein.
index.js von der Annahme, dass die Dateien 
index.js und 
App.js jetzt leer sind, werden Sie als erste Aufgabe aufgefordert, den Code 
index.js zu schreiben, die einfachste Komponente in 
App.js und in 
App.js index.js .
index.js sollte in 
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 importieren wir 
React und 
ReactDOM , importieren Stile aus 
index.css und der 
App Komponente. AnschlieĂźend 
ReactDOM.render() wir mithilfe der 
ReactDOM.render() -Methode das, was die 
App Komponente bildet, in das Element der 
index.html Seite mit der 
root <div id="root"></div> ( 
<div id="root"></div> ).
So könnte die 
App.js Datei aussehen:
 import React from "react" function App() {   return (       <h1>Hello world!</h1>   ) } export default App 
Hier wird nun die einfachste Funktionskomponente vorgestellt.
Zu diesem Zeitpunkt sieht das Projekt wie das unten gezeigte aus.
Anwendung im BrowserErstellen Sie nun zwei neue Komponenten in zwei Dateien, deren Namen den Namen der Komponenten entsprechen:
- Die HeaderKomponente, mit der der Anwendungsheader angezeigt wird.
- Die MemeGeneratorKomponente, in der die der Anwendung zugewiesenen Hauptaufgaben gelöst werden. Hier werden nämlich Aufrufe der API ausgeführt. Anwendungsdaten werden hier gespeichert.
Ăśberlegen Sie sich, welche Funktionen diesen Komponenten zugewiesen sind.
Hier ist der Inhalt der Datei 
Header.js :
 import React from "react" function Header() {   return (       <h1>HEADER</h1>   ) } export default Header 
Da diese Komponente nur zur Anzeige des Anwendungsheaders verwendet wird, haben wir sie als Funktionskomponente konzipiert.
Hier ist der Code fĂĽr die Datei 
MemeGenerator.js :
 import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state ={}   }     render() {       return (           <h1>MEME GENERATOR SECTION</h1>       )   } } export default MemeGenerator 
Unter BerĂĽcksichtigung der Aufgaben, die mit der 
MemeGenerator Komponente gelöst werden sollen, verwenden wir hier eine Komponente, die auf der Klasse basiert. Hier gibt es einen Konstruktor, in dem wir den Zustand mit einem leeren Objekt initialisieren.
Nachdem wir diese Dateien erstellt haben, importieren wir sie in 
App.js und geben das Markup von der Funktionskomponente der 
App , die Instanzen dieser Komponenten verwendet. Dabei ist nicht zu vergessen, dass die Funktionskomponente, wenn sie mehrere Elemente zurĂĽckgibt, in etwas eingeschlossen werden muss. In unserem Fall ist dies das 
<div> . Hier ist der aktualisierte 
App.js Code:
 import React from "react" import Header from "./Header" import MemeGenerator from "./MemeGenerator" function App() {   return (       <div>           <Header />           <MemeGenerator />       </div>   ) } export default App 
ĂśberprĂĽfen Sie das Erscheinungsbild der Anwendung.
Anwendung im BrowserLassen Sie uns nun an der 
Header Komponente arbeiten. Hier verwenden wir das semantische Element HTML5 
<header> . Dieses Tag enthält das Bild und den Text. Nun 
Header.js der Code der Datei 
Header.js aus:
 import React from "react" function Header() {   return (       <header>           <img               src="http://www.pngall.com/wp-content/uploads/2016/05/Trollface.png"               alt="Problem?"           />           <p>Meme Generator</p>       </header>   ) } export default Header 
So ändert sich das Aussehen der App.
Anwendung im BrowserDer Titel der Anwendung entspricht den zuvor in 
index.js . Die Arbeit an der 
Header Komponente ist nun abgeschlossen.
Beschäftigen 
MemeGenerator weiterhin mit der 
MemeGenerator Komponente. Jetzt können Sie den Status dieser Komponente unabhängig initialisieren, indem Sie die folgenden Daten darauf schreiben:
- Der Text, der oben im Mem angezeigt wird (Eigenschaft topText).
- Der am unteren Rand des Memes angezeigte Text (Eigenschaft bottomText).
- Zufälliges Bild ( randomImageEigenschaft, die mit dem Link http://i.imgflip.com/1bij.jpg initialisiert werden muss).
Dies ist der Code von 
MemeGenerator.js nach der Initialisierung des Status:
 import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg"       }   }     render() {       return (           <h1>MEME GENERATOR SECTION</h1>       )   } } export default MemeGenerator 
Jetzt wird das Erscheinungsbild der Anwendung nicht beeinflusst.
Wir werden Aufrufe an die API verwenden, die ein Array von Objekten zurückgibt, die Links zu Bildern enthalten, auf deren Grundlage Memes erstellt werden können. In dieser Phase der Projektarbeit werden Sie aufgefordert, die folgenden Funktionen in der 
MemeGenerator Komponente zu implementieren:
Hier wird zur Verdeutlichung ein Fragment der JSON-Daten beim Zugriff auf diese API zurĂĽckgegeben:
 {   "success":true,  "data":{      "memes":[         {           "id":"112126428",           "name":"Distracted Boyfriend",           "url":"https:\/\/i.imgflip.com\/1ur9b0.jpg",           "width":1200,           "height":800,           "box_count":3        },        {           "id":"87743020",           "name":"Two Buttons",           "url":"https:\/\/i.imgflip.com\/1g8my4.jpg",           "width":600,           "height":908,           "box_count":2        },        {           "id":"129242436",           "name":"Change My Mind",           "url":"https:\/\/i.imgflip.com\/24y43o.jpg",           "width":482,           "height":361,           "box_count":2        },        ….  ]  } } 
Um das oben gestellte Problem zu lösen, muss berücksichtigt werden, dass es sich um die Daten handelt, die die Komponente zu Beginn der Anwendung benötigt.
Um sie zu laden, greifen wir daher auf die 
componentDidMount() . Hier rufen wir mit der Standardmethode 
fetch() die API auf. Es gibt ein Versprechen zurĂĽck. Nach dem Laden der Daten steht uns das 
allMemeImgs zur VerfĂĽgung. Wir extrahieren das 
memes Array daraus und 
allMemeImgs es in die neue 
allMemeImgs , die mit einem leeren Array initialisiert wurde. Da diese Daten noch nicht verwendet werden, um etwas zu bilden, das auf dem Bildschirm angezeigt wird, drucken wir das erste Element des Arrays auf die Konsole, um die korrekte Funktion des Datenlademechanismus zu ĂĽberprĂĽfen.
Hier ist der Code der 
MemeGenerator Komponente in dieser Arbeitsphase:
 import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               console.log(memes[0])               this.setState({ allMemeImgs: memes })           })   }     render() {       return (           <h1>MEME GENERATOR SECTION</h1>       )   } } export default MemeGenerator 
Dies gelangt nach erfolgreichem Laden der Daten zur Konsole.
Anwendung im Browser, Ausgabe an die Konsole des ersten Elements des geladenen ArraysBeachten Sie, dass das Bild mit vielen Eigenschaften beschrieben wird. Wir verwenden nur die 
url Eigenschaft, die den Zugriff auf den Link zum Herunterladen des Bildes ermöglicht.
Zu Beginn des Kurses haben wir darĂĽber gesprochen, wie diese Anwendung aussehen wird.
Meme GeneratorDie Benutzeroberfläche verfügt insbesondere über einige Felder zur Texteingabe, die im oberen und unteren Teil des Bildes angezeigt werden. Nun sind Sie eingeladen, basierend auf dem unten gezeigten aktualisierten Code der 
MemeGenerator Komponente, der sich vom obigen Code dieser Komponente dadurch unterscheidet, dass hier ein Formular leer hinzugefĂĽgt wird, einige Textfelder, 
topText und 
bottomText zu erstellen. Beachten Sie, dass diese Komponenten verwaltet werden mĂĽssen. FĂĽgen Sie ihnen die erforderlichen Attribute hinzu. Erstellen Sie einen 
onChange Ereignishandler 
onChange diese Felder, in dem Sie die entsprechenden 
onChange aktualisieren mĂĽssen, wenn Sie Text in sie eingeben.
 import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     render() {       return (           <div>               <form className="meme-form">                   {                       //                        }                                 <button>Gen</button>               </form>           </div>       )   } } export default MemeGenerator 
Beachten Sie ĂĽbrigens, dass wir einen Kommentar in geschweifte Klammern setzen, um einen Kommentar in den von der 
render() -Methode zurĂĽckgegebenen Code aufzunehmen, um dem System anzuzeigen, dass dieses Fragment als JavaScript-Code interpretiert werden soll.
Folgendes sollten Sie in dieser Phase der Arbeit an der Anwendung erhalten:
 import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }       this.handleChange = this.handleChange.bind(this)   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     handleChange(event) {       const {name, value} = event.target       this.setState({ [name]: value })   }     render() {       return (           <div>               <form className="meme-form">                   <input                       type="text"                       name="topText"                       placeholder="Top Text"                       value={this.state.topText}                       onChange={this.handleChange}                   />                   <input                       type="text"                       name="bottomText"                       placeholder="Bottom Text"                       value={this.state.bottomText}                       onChange={this.handleChange}                   />                                 <button>Gen</button>               </form>           </div>       )   } } export default MemeGenerator 
Jetzt sieht die Anwendungsseite wie unten gezeigt aus.
Anwendung im BrowserWährend nur Felder mit Hilfetext angezeigt werden, führt die Eingabe von Daten nicht zu Änderungen in der Benutzeroberfläche. Um den korrekten Betrieb der hier implementierten Mechanismen zu überprüfen, können Sie den Befehl 
console.log() .
Jetzt arbeiten wir an dem Teil der Anwendung, der fĂĽr die Anzeige des Bildmems verantwortlich ist. Denken Sie daran, dass wir jetzt ein Array mit Informationen zu Bildern haben, die als Grundlage fĂĽr Memes dienen sollen. Die Anwendung sollte durch DrĂĽcken der 
Gen Taste zufällig ein Bild aus diesem Array auswählen und ein Mem bilden.
Hier ist der aktualisierte Code fĂĽr die 
MemeGenerator Komponente. Hier gibt es in der 
render() -Methode unterhalb des Formularbeschreibungscodes ein 
<div> -Element, das ein 
<img> -Element enthält, das ein Bild anzeigt, und einige 
<h2> -Elemente, die Beschriftungen anzeigen. Die Elemente 
<div> und 
<h2> werden mit Stilen entworfen, die wir dem Projekt zu Beginn der Arbeit hinzugefĂĽgt haben.
 import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }       this.handleChange = this.handleChange.bind(this)   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     handleChange(event) {       const {name, value} = event.target       this.setState({ [name]: value })   }     render() {       return (           <div>               <form className="meme-form">                   <input                       type="text"                       name="topText"                       placeholder="Top Text"                       value={this.state.topText}                       onChange={this.handleChange}                   />                   <input                       type="text"                       name="bottomText"                       placeholder="Bottom Text"                       value={this.state.bottomText}                       onChange={this.handleChange}                   />                                 <button>Gen</button>               </form>               <div className="meme">                   <img align="center" src={this.state.randomImg} alt="" />                   <h2 className="top">{this.state.topText}</h2>                   <h2 className="bottom">{this.state.bottomText}</h2>               </div>           </div>       )   } } export default MemeGenerator 
So sieht die App jetzt aus.
Anwendung im BrowserBeachten Sie, dass hier das Bild angezeigt wird, das den Status initialisiert hat. Wir verwenden noch keine Bilder, die in der State-Eigenschaft 
allMemeImgs gespeichert sind. Versuchen wir, etwas in die Textfelder einzugeben.
Anwendung im BrowserWie Sie sehen können, funktionieren die für die Arbeit mit Text verantwortlichen Anwendungssubsysteme wie erwartet. Jetzt muss nur noch sichergestellt werden, dass durch Drücken der 
Gen Taste ein zufälliges Bild aus dem Array mit Bilddaten ausgewählt und in das 
<img> -Element geladen wird, das sich auf der Seite unter den Texteingabefeldern befindet.
Führen Sie die folgende Aufgabe aus, um die Anwendung mit dieser Funktion auszustatten. Erstellen Sie eine Methode, die ausgelöst wird, wenn Sie auf die Schaltfläche 
Gen klicken. Diese Methode sollte eines der Bilder auswählen, deren Informationen in der state-Eigenschaft 
allMemeImgs gespeichert 
allMemeImgs , und dann Aktionen ausfĂĽhren, mit denen Sie dieses Bild im 
<img> -Element unter den Texteingabefeldern anzeigen können. 
allMemeImgs dass 
allMemeImgs ein Array von Objekten speichert, die Bilder beschreiben, und dass jedes Objekt aus diesem Array eine 
url Eigenschaft hat.
Hier ist der Code, der eine Lösung für dieses Problem bietet:
 import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }       this.handleChange = this.handleChange.bind(this)       this.handleSubmit = this.handleSubmit.bind(this)   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     handleChange(event) {       const {name, value} = event.target       this.setState({ [name]: value })   }     handleSubmit(event) {       event.preventDefault()       const randNum = Math.floor(Math.random() * this.state.allMemeImgs.length)       const randMemeImg = this.state.allMemeImgs[randNum].url       this.setState({ randomImg: randMemeImg })   }     render() {       return (           <div>               <form className="meme-form" onSubmit={this.handleSubmit}>                   <input                       type="text"                       name="topText"                       placeholder="Top Text"                       value={this.state.topText}                       onChange={this.handleChange}                   />                   <input                       type="text"                       name="bottomText"                       placeholder="Bottom Text"                       value={this.state.bottomText}                       onChange={this.handleChange}                   />                                 <button>Gen</button>               </form>               <div className="meme">                   <img align="center" src={this.state.randomImg} alt="" />                   <h2 className="top">{this.state.topText}</h2>                   <h2 className="bottom">{this.state.bottomText}</h2>               </div>           </div>       )   } } export default MemeGenerator 
Der Schaltfläche 
Gen kann ein Ereignishandler zugewiesen werden, der beim Klicken darauf auftritt, wie dies bei allen anderen Schaltflächen der Fall ist. Angesichts der Tatsache, dass diese Schaltfläche zum 
onSubmit des Formulars verwendet wird, ist es jedoch besser, den 
onSubmit Ereignishandler 
onSubmit Formulars zu verwenden. In diesem Handler 
handleSubmit() rufen wir die Methode des Ereignisses 
event.preventDefault() auf, um das Standardverfahren zum 
event.preventDefault() von 
event.preventDefault() abzubrechen, bei dem die Seite neu geladen wird. Als nächstes erhalten wir eine Zufallszahl im Bereich von 0 bis zu dem Wert, der dem Index des letzten Elements des 
allMemeImgs Arrays entspricht, und verwenden diese Zahl, um auf das Element mit dem entsprechenden Index zu verweisen. Wenn wir uns dem Element 
randomImg , das das Objekt ist, erhalten wir die Eigenschaft dieser Objekt- 
url und schreiben sie in die 
randomImg . Danach wird die Komponente neu gerendert und das Erscheinungsbild der Seite geändert.
Anwendungsseite im BrowserKursprojekt abgeschlossen.
Zusammenfassung
In dieser Lektion haben Sie eine Anwendung erstellt, die das verwendet, was Sie beim Beherrschen von React gelernt haben. Das nächste Mal werden wir über die Entwicklung moderner React-Anwendungen sprechen und Projektideen diskutieren, deren Implementierung Sie in der Arbeit mit React üben können.
Liebe Leser! Haben Sie beim Abschluss dieses Kursprojekts Schwierigkeiten gehabt?