Μάθετε το React δημιουργώντας μια γεννήτρια Meme

Τα Memes είναι υπέροχα - είναι ένας πολύ διασκεδαστικός τρόπος για την περιγραφή ιδεών και απόψεων. Επομένως, δεν είναι τυχαίο που διάλεξα μια εφαρμογή δημιουργίας meme ως έργο capstone στο δωρεάν μάθημα React στο Scrimba Η εφαρμογή λειτουργεί τραβώντας μια τυχαία εικόνα meme από ένα API και τοποθετώντας το κείμενό σας πάνω από αυτήν για να δημιουργήσετε το δικό σας, εξατομικευμένο meme.

Έτσι, σε αυτό το άρθρο, θα σας δώσω έναν βήμα προς βήμα οδηγό για τη δημιουργία της εφαρμογής. Εάν έχετε μπερδευτεί ποτέ, μπορείτε επίσης να ακολουθήσετε αυτά τα βήματα στο μάθημα Scrimba, ξεκινώντας από αυτήν τη διάλεξη.

Και τότε, αν σας αρέσει το στυλ διδασκαλίας μου και έχετε τη διάθεση για μια πιο δύσκολη πρόκληση αφού ολοκληρώσετε αυτό το σεμινάριο, ρίξτε μια ματιά στο επερχόμενο προχωρημένο μάθημα για το Scrimba

Σημείωση: Θα πρέπει ήδη να είστε αρκετά εξοικειωμένοι με ορισμένες από τις θεμελιώδεις έννοιες του React, όπως τα στοιχεία, η κατάσταση, τα στηρίγματα και οι μέθοδοι κύκλου ζωής. Επίσης, αυτό το σεμινάριο δεν χρησιμοποιεί Hooks, αλλά στο επερχόμενο μάθημά μου θα καλύψουμε σε βάθος τα Hooks και θα εξασκηθούμε σε πολλά.

1. Δημιουργία πλάκας boiler και απόδοση ενός στοιχείου εφαρμογής

Δημιουργία της εργασίας του boilerplate

Το πρώτο πράγμα που πρέπει να κάνουμε είναι να δημιουργήσουμε τον κωδικό boilerplate για την εφαρμογή. Για να γίνει αυτό, εισάγουμε Reactκαι ReactDOMχρησιμοποιούμε ReactDOMγια να αποδώσουμε ένα στοιχείο που ονομάζεται App, το οποίο θα δημιουργήσουμε αργότερα. Στη συνέχεια, βάζουμε το Appστοιχείο στο «root». Εισάγουμε επίσης Appαπό το αρχείο του "./App", το οποίο θα δημιουργήσουμε σύντομα.

// index.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render(, document.getElementById('root')); 

Στη συνέχεια, δημιουργούμε το App.jsαρχείο μας . Σε αυτό, δημιουργούμε ένα λειτουργικό στοιχείο που ονομάζεται το Appοποίο, προς το παρόν, επιστρέφει ένα απλό

. Στη συνέχεια το εξάγουμε. ο

μας επιτρέπει να ελέγξουμε ότι η εφαρμογή εμφανίζεται σωστά στην οθόνη.

import React from 'react'; function App() { return 

Hello world!

; } export default App;

Η προκύπτουσα έξοδος είναι αυτή:

Γεια σας Κόσμος

2. Δημιουργία στοιχείων Header και MemeGenerator

Δημιουργία εργασίας Header και MemeGenerator

Στη συνέχεια, δημιουργούμε τα στοιχεία Header και MemeGenerator. Η κεφαλίδα θα εμφανίζει μόνο στοιχεία, ενώ το MemeGenerator θα καλεί στο API και θα διατηρεί τα δεδομένα σε κατάσταση.

Ας ξεκινήσουμε δημιουργώντας το Header.jsαρχείο. Δεδομένου ότι το Header είναι ένα στοιχείο που χρησιμοποιείται μόνο για εμφάνιση, θα πρέπει να είναι λειτουργικό στοιχείο. Προς το παρόν, το στοιχείο θα πρέπει να επιστρέψει ένα απλό

. Μετά τη δημιουργία του, εξάγουμε στη συνέχεια την κεφαλίδα.

import React from 'react'; function Header() { return 

HEADER

; } export default Header;

Στη συνέχεια, δημιουργούμε το MemeGenerator.jsαρχείο. Καθώς το MemeGeneratorστοιχείο θα κρατά δεδομένα και πραγματοποιεί κλήσεις σε ένα API, πρέπει να είναι ένα στοιχείο κλάσης. Πρέπει ακόμη να εισαγάγουμε το React, και δεδομένου ότι πρόκειται να είναι ένα συστατικό κλάσης, θα το εισαγάγουμε Componentεπίσης (το οποίο ονομάζεται εισαγωγή)

Το MemeGenerator χρειάζεται ένα constructor()που καλεί super()και όπως θα κρατήσει κατάσταση, προσθέτουμε κάποια κενή κατάσταση σε αυτό τώρα. Όπως και στο στοιχείο Header, κάνουμε ένα απλό

να ξεκινήσει με. Στη συνέχεια εξάγουμε το MemeGenerator.

import React, { Component } from 'react'; class MemeGenerator extends Component { constructor() { super(); this.state = {}; //empty state } render() { return 

MEME GENERATOR SECTION

; } } export default MemeGenerator;

Τώρα, εισάγουμε τόσο το Header όσο και το MemeGenerator App.jsκαι δημιουργούμε μια παρουσία καθενός στο στοιχείο εφαρμογής μας. Για να εμφανίζονται σωστά τα στοιχεία, θα τα τυλίγουμε σε ένα .

import React from 'react'; import Header from './Header'; import MemeGenerator from './MemeGenerator'; function App() { return ( ); } export default App; 

3. Ολοκλήρωση του στοιχείου Header.

To complete the component, we add a trollface image by inserting an tag and setting the src to the image's URL. We then add a

tag with the name of our app and wrap them both in the semantic HTML5 tag.

function Header() { return (  Problem?

Meme Generator

); }

As styling is outside the scope of this course, the CSS styles have already been created and applied to the tag. The result is this:

Έγινε κεφαλίδα

That said, learners can always play around with the styling and hone their CSS skills by themselves. With the now complete, the rest of the challenge will take place in

4. Initializing state

Εκκίνηση εργασίας κατάστασης

We now have to initialize state so that it saves a top text, a bottom text and a random image, which is already supplied.

To do this, we build up the empty object we placed in the when we originally built it. We initialize topText and bottomText as empty strings and randomImg as the provided URL.

class MemeGenerator extends Component { constructor() { super(); this.state = { topText: '', bottomText: '', randomImg: '//i.imgflip.com/1bij.jpg' }; } } 

5. Making the API call

Πραγματοποίηση της εργασίας κλήσης API

Next, we make an API call to the provided URL and save the data returned (which is an array found in response.data.memes) to a new state property called allMemeImgs.

When we need to load data from an endpoint to use in our component, a good place to make the request is the componentDidMount() lifecycle method. As soon as the component mounts, we use the native fetch() function to call to the provided URL.

componentDidMount() { fetch("//api.imgflip.com/get_memes") } 

This returns a promise which we turn into a Javascript object with the .json() method.

componentDidMount() { fetch("//api.imgflip.com/get_memes") .then(response => response.json()) } 

Then we get the response which is useful to us by pulling the memes array from response.data.

componentDidMount() { fetch("//api.imgflip.com/get_memes") .then(response => response.json()) .then(response => { const { memes } = response.data }) } 

Now, we save the results to a new state property called allMemeImgs. To do this, we initialize allMemeImgs as an empty array.

this.state = { topText: '', bottomText: '', randomImg: '//i.imgflip.com/1bij.jpg', allMemeImgs: [] }; 

Now, back in componentDidMount(), we set state. As we are not interested in what the previous state was, we set allMemeImgs to memes.

componentDidMount() { fetch("//api.imgflip.com/get_memes") .then(response => response.json()) .then(response => { const { memes } = response.data this.setState({ allMemeImgs: memes }) }) } 

To ensure that it works, we console.log the first item, which looks something like this:

έξοδος console.log

Here's an overview of the entire componentDidMount() function.

componentDidMount() { //ensure that data is fetched at the beginning fetch("//api.imgflip.com/get_memes") //call to URL .then(response => response.json()) //turn promise into JS object .then(response => { const { memes } = response.data //pull memes array from response.data console.log(memes[0]) // check data is present this.setState({ allMemeImgs: memes }) // set allMemeImgs state }) } 

6. Creating the input form

We now want to create a form which will eventually allow the user to input the top and bottom texts. We do this with an HTML tag and a simple which says 'Gen'. We style it with the pre-provided CSS.

render() { return ( Gen ) } 

Κουμπί "Γενεμένο"

7. Adding input fields to the form

Προσθήκη εργασίας πεδίων εισαγωγής

Next, it is up to us to add the two input fields (one for the top text and one for the bottom text). The form should be a controlled form, so we will need to add all the attributes needed in order for that to work. We will create the onChange handler later.

We create two input fields which both have the type text and appropriate name attributes (topText and bottomText). Rather than using labels, we use placeholders: 'Top Text' and 'Bottom Text'.

Lastly, in order to make this a controlled form, we set the value as equal to the current value in state with {this.state.topText} and {this.state.bottomText}.

render() { return ( Gen ) } 

8. Creating the onChange handler.

Δημιουργία της εργασίας χειριστή onChange

Now, we create the onChange handler, which will update the corresponding state on every change of the input field.

First, we create a handleChange() function which receives an event.

handleChange(event) { } 

Now, we set the onChange of both input fields to equal handleChange.

   Gen  

We need to remember to bind the method in the constructor — a common gotcha for React developers.

constructor() { super() this.state = { topText: "", bottomText: "", randomImg: "//i.imgflip.com/1bij.jpg", allMemeImgs: [] } this.handleChange = this.handleChange.bind(this) } 

To test the new handleChange() function, we add a simple console.log:

handleChange(event) { console.log("Working!") } 

If it is correctly firing, you'll see something like this:

Κατανεμημένη κονσόλα.log (

Now to fill in the handleChange() function. To do this, we want to pull the name and value properties from event.target so that we can get the name of the state we are supposed to update (topText or bottomText) and the value which is typed into the box.

handleChange(event) { const { name, value } = event.target } 

We will now use these to update state. As we are not interested in what the previous state was, we can just provide an object in which we set the [name] to the value typed into the input field.

handleChange(event) { const {name, value} = event.target this.setState({ [name]: value }) } 

9. Displaying a meme image alongside the top and bottom text

We now want the app to display a meme image alongside the top and bottom text. We insert an tag underneath the and set the randomImg which we initialized as its source by using src={this.state.randomImg}. We then add two

tags which display the corresponding text which is also saved in state. All of this is wrapped in a div and styled with the pre-provided meme class.

{this.state.topText}

{this.state.bottomText}

We can now test the app by typing into the text boxes. As state is being correctly set on every keystroke, the text displayed on the image changes each time we type.

Έδωσε μέχρι τώρα παράδειγμα προόδου

10. Displaying a random meme image alongside the Top and Bottom text

Εμφάνιση μιας εργασίας τυχαίας εικόνας meme

Now, we need to create a method which displays a meme image which it randomly chooses from our allMemeImgs array when the Gen button is clicked. The property on the chosen image in the array is .url.

We can break this task down into smaller parts.

Firstly, we set the form's onSubmit to equal the name of our new method, which we will call handleSubmit().

We now create the handleSubmit() function above the render() function. We need to preventDefault on the event, otherwise, the method will try to refresh the page.

handleSubmit(event) { event.preventDefault() } 

We also need to bind handleSubmit() in our constructor().

constructor() { super() this.state = { topText: "", bottomText: "", randomImg: "//i.imgflip.com/1bij.jpg", allMemeImgs: [] } this.handleChange = this.handleChange.bind(this) this.handleSubmit = this.handleSubmit.bind(this) } 

Now, we need to get a random number, get the meme from that index and set randomImg to the .url of the random item.

handleSubmit(event) { event.preventDefault() // get a random int (index in the array) // get the meme from that index // set `randomImg` to the `.url` of the random item I grabbed } 

To get a random number, we use Math.floor(Math.random). To make sure that it is one of the indices in our allMemeImgs array, we multiply by the length of the array.

const randNum = Math.floor(Math.random() * this.state.allMemeImgs.length); 

We now set randMemeImg to equal allMemeImgs, with the index of allMemeImgs as the randNum we just got. We then add .url to the end of it.

const randMemeImg = this.state.allMemeImgs[randNum].url; 

Now, all we need to do is update the state by updating the randomImg property with randMemeImg.

this.setState({ randomImg: randMemeImg }); 

Our completed handleSubmit() function looks like this:

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

Completed Meme Generator

Εφαρμογή εργασίας

We now have completed the meme generator app, and get a different image every time we hit the Gen button, which is then overlaid with the text we input.

Για να προωθήσουμε τη μάθησή μας, θα μπορούσαμε να παίξουμε με κώδικα και να δούμε αν μπορούμε να το βελτιώσουμε ή να προσπαθήσουμε να πάρουμε εικόνες από ένα διαφορετικό API. Για κάποια πρακτική βαρέως τύπου, θα μπορούσαμε ακόμη και να διαγράψουμε όλο τον κώδικα και να προσπαθήσουμε να τον δημιουργήσουμε ξανά από την αρχή.

Συγχαρητήρια για την παρακολούθηση του σεμιναρίου και την εκμάθηση όλων των δεξιοτήτων που χρησιμοποιούνται σε αυτό το έργο.

Και αν είστε έτοιμοι για αυτό, ρίξτε μια ματιά στο επερχόμενο προηγμένο μάθημά μου, καθώς θα σας οδηγήσει σε επαγγελματικό επίπεδο στο React!