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
Header
Komponente, mit der der Anwendungsheader angezeigt wird. - Die
MemeGenerator
Komponente, 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 (
randomImage
Eigenschaft, 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?