Di bagian terjemahan kursus pelatihan Bereaksi ini, Anda diminta untuk membuat generator meme.

→
Bagian 1: ikhtisar kursus, alasan popularitas React, ReactDOM dan JSX→
Bagian 2: komponen fungsional→
Bagian 3: file komponen, struktur proyek→
Bagian 4: komponen induk dan anak→
Bagian 5: mulai bekerja pada aplikasi TODO, dasar-dasar gaya→
Bagian 6: tentang beberapa fitur kursus, JSX dan JavaScript→
Bagian 7: gaya inline→
Bagian 8: terus bekerja pada aplikasi TODO, terbiasa dengan sifat-sifat komponen→
Bagian 9: properti komponen→
Bagian 10: Workshop bekerja dengan properti komponen dan gaya→
Bagian 11: pembuatan markup dinamis dan metode susunan peta→
Bagian 12: lokakarya, pekerjaan tahap ketiga pada aplikasi TODO→
Bagian 13: komponen berbasis kelas→
Bagian 14: lokakarya tentang komponen berbasis kelas, status komponen→
Bagian 15: bengkel kesehatan komponen→
Bagian 16: tahap keempat dari pengerjaan aplikasi TODO, penanganan acara→
Bagian 17: tahap kelima bekerja pada aplikasi TODO, memodifikasi status komponen→
Bagian 18: tahap keenam dari pengerjaan aplikasi TODO→
Bagian 19: metode siklus hidup komponenBagian 20: pelajaran pertama dalam rendering bersyarat→
Bagian 21: pelajaran kedua dan lokakarya tentang rendering bersyarat→
Bagian 22: tahap ketujuh bekerja pada aplikasi TODO, mengunduh data dari sumber eksternal→
Bagian 23: pelajaran pertama tentang bekerja dengan formulir→
Bagian 24: Pelajaran Bentuk Kedua→
Bagian 25: Workshop bekerja dengan formulir→
Bagian 26: arsitektur aplikasi, pola Container / Komponen→
Bagian 27: proyek kursusPelajaran 45. Proyek kursus. Generator Meme
→
AsliJadi kami sampai di proyek kursus. Mari kita buat aplikasi yang akan menghasilkan meme. Mari kita mulai dengan proyek aplikasi create-react-app standar yang dibuat menggunakan perintah ini:
npx create-react-app meme-generator
Di sini Anda dapat menemukan informasi tentang fitur penggunaannya.
Dalam proses pengerjaan proyek ini, Anda akan diminta untuk mengimplementasikan sendiri beberapa bagiannya, dan kemudian membaca penjelasan tentangnya. Proyek standar sudah memiliki kode boilerplate yang terletak, khususnya, dalam file
index.js
dan
App.js
Anda dapat menghapus kode ini sepenuhnya dan mencoba menulisnya sendiri untuk menguji diri Anda dalam penerapan mekanisme standar React-aplikasi.
Dalam proyek ini, Anda diundang untuk menggunakan gaya berikut:
* { 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 }
Gaya-gaya ini dapat dimasukkan dalam file
index.css
sudah ada dalam proyek dan
index.css
dalam file
index.js
.
Jadi, berdasarkan asumsi bahwa file
index.js
dan
App.js
sekarang kosong, Anda, sebagai tugas pertama, diundang untuk menulis kode
index.js
, membuat komponen paling sederhana di
App.js
dan mengeluarkannya ke
index.js
.
Inilah yang seharusnya muncul di
index.js
:
import React from "react" import ReactDOM from "react-dom" import './index.css' import App from "./App" ReactDOM.render(<App />, document.getElementById("root"))
Di sini kita mengimpor
React
dan
ReactDOM
, mengimpor gaya dari
index.css
dan komponen
App
. Setelah itu, menggunakan metode
ReactDOM.render()
, kami
ReactDOM.render()
apa yang komponen
App
bentuk menjadi elemen halaman
index.html
dengan pengidentifikasi
root
(
<div id="root"></div>
).
App.js
inilah
App.js
file
App.js
:
import React from "react" function App() { return ( <h1>Hello world!</h1> ) } export default App
Di sini sekarang disajikan komponen fungsional yang paling sederhana.
Pada tahap ini, proyek terlihat seperti yang ditunjukkan di bawah ini.
Aplikasi di browserSekarang buat dua komponen baru, dalam dua file yang namanya sesuai dengan nama-nama komponen:
- Komponen
Header
yang akan digunakan untuk menampilkan header aplikasi. - Komponen
MemeGenerator
, di mana tugas utama yang ditetapkan untuk aplikasi akan diselesaikan. Yaitu, panggilan ke API akan dilakukan di sini. Data aplikasi akan disimpan di sini.
Mempertimbangkan fungsi apa yang ditugaskan pada komponen-komponen ini, pikirkan tentang apa yang seharusnya.
Berikut ini isi file
Header.js
:
import React from "react" function Header() { return ( <h1>HEADER</h1> ) } export default Header
Karena komponen ini hanya akan digunakan untuk menampilkan header aplikasi, kami mendesainnya sebagai komponen fungsional.
Berikut ini kode untuk file
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
Di sini, dengan mempertimbangkan tugas-tugas yang seharusnya diselesaikan dengan menggunakan komponen
MemeGenerator
, kami akan menggunakan komponen berdasarkan kelas. Ada konstruktor di sini di mana kita menginisialisasi keadaan dengan objek kosong.
Setelah membuat file-file ini, kami mengimpornya ke
App.js
dan mengembalikan markup dari komponen fungsional
App
, yang menggunakan instance dari komponen-komponen ini, tidak lupa bahwa jika komponen fungsional mengembalikan beberapa elemen, mereka harus dibungkus dengan sesuatu. Dalam kasus kami, ini adalah
<div>
. Berikut adalah kode
App.js
diperbarui:
import React from "react" import Header from "./Header" import MemeGenerator from "./MemeGenerator" function App() { return ( <div> <Header /> <MemeGenerator /> </div> ) } export default App
Periksa tampilan aplikasi.
Aplikasi di browserSekarang mari kita bekerja pada komponen
Header
. Di sini kita akan menggunakan elemen semantik HTML5
<header>
. Tag ini akan berisi gambar dan teks. Sekarang kode file
Header.js
akan terlihat seperti ini:
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
Begini cara tampilan aplikasi akan berubah.
Aplikasi di browserJudul aplikasi dirancang sesuai dengan gaya yang sebelumnya
index.js
dalam
index.js
. Bekerja pada komponen
Header
sekarang selesai.
Kami akan terus berurusan dengan komponen
MemeGenerator
. Sekarang Anda diundang untuk secara mandiri menginisialisasi keadaan komponen ini dengan menulis data berikut ini:
- Teks ditampilkan di bagian atas meme (properti
topText
). - Teks ditampilkan di bagian bawah meme (properti
bottomText
). - Gambar acak (properti
randomImage
yang perlu diinisialisasi dengan tautan http://i.imgflip.com/1bij.jpg ).
Inilah yang akan menjadi kode
MemeGenerator.js
setelah menginisialisasi 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
Sekarang penampilan aplikasi tidak akan terpengaruh.
Kami akan menggunakan panggilan ke API, yang mengembalikan array objek yang berisi tautan ke gambar, berdasarkan meme mana yang dapat dibuat. Pada tahap kerja proyek ini, Anda diundang untuk mengimplementasikan fungsionalitas berikut dalam komponen
MemeGenerator
:
Di sini, untuk membuatnya lebih jelas, sebuah fragmen data JSON dikembalikan saat mengakses API ini:
{ "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 }, …. ] } }
Memecahkan masalah yang diajukan di atas, perlu untuk mempertimbangkan fakta bahwa kita berbicara tentang data yang dibutuhkan komponen pada awal aplikasi.
Oleh karena itu, untuk memuatnya, kami akan menggunakan metode daur hidup
componentDidMount()
. Di sini kita, menggunakan metode
fetch()
standar
fetch()
, akan memanggil API. Itu mengembalikan janji. Setelah memuat data, objek respons akan tersedia untuk kita, dari situ kita mengekstrak array
memes
dan memasukkannya ke dalam properti state baru
allMemeImgs
, diinisialisasi dengan array kosong. Karena data ini belum digunakan untuk membentuk sesuatu yang ditampilkan di layar, kami akan mencetak elemen pertama dari array ke konsol untuk memeriksa operasi yang benar dari mekanisme pemuatan data.
Berikut adalah kode komponen
MemeGenerator
pada tahap kerja ini:
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
Inilah yang sampai ke konsol setelah berhasil memuat data.
Aplikasi di browser, output ke konsol dari elemen pertama dari array yang dimuatPerhatikan bahwa gambar dijelaskan menggunakan banyak properti. Kami hanya akan menggunakan properti
url
, yang memberikan akses ke tautan untuk mengunduh gambar.
Pada awal kursus, kami berbicara tentang bagaimana tampilan aplikasi ini.
Generator MemeSecara khusus, antarmuka memiliki beberapa bidang untuk memasukkan teks, yang akan ditampilkan di bagian atas dan bawah gambar. Sekarang Anda diundang untuk mengambil, berdasarkan kode yang diperbarui dari komponen
MemeGenerator
diperlihatkan di bawah ini, yang berbeda dari kode di atas dari komponen ini di mana formulir kosong ditambahkan di sini, untuk membuat beberapa bidang teks,
topText
dan
bottomText
. Perlu diingat bahwa komponen ini harus dikelola. Tambahkan atribut yang diperlukan padanya. Buat event
onChange
bidang-bidang ini di mana Anda perlu memperbarui properti negara terkait saat Anda memasukkan teks di dalamnya.
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
Ngomong-ngomong, perhatikan fakta bahwa untuk memasukkan komentar dalam kode yang dikembalikan oleh metode
render()
, kami melampirkannya dalam kurung keriting untuk menunjukkan kepada sistem bahwa fragmen ini harus ditafsirkan sebagai kode JavaScript.
Inilah yang harus Anda dapatkan pada tahap pengerjaan aplikasi ini:
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
Sekarang halaman aplikasi akan terlihat seperti yang ditunjukkan di bawah ini.
Aplikasi di browserMeskipun hanya bidang dengan teks bantuan yang ditampilkan, memasukkan data ke dalamnya tidak menyebabkan perubahan pada antarmuka. Untuk memverifikasi operasi mekanisme yang diterapkan di sini, Anda dapat menggunakan perintah
console.log()
.
Sekarang kami akan bekerja pada bagian aplikasi yang bertanggung jawab untuk menampilkan meme gambar. Ingatlah bahwa sekarang kami memiliki larik yang berisi informasi tentang gambar yang rencananya akan digunakan sebagai dasar meme. Aplikasi harus, dengan menekan tombol
Gen
, secara acak memilih gambar dari array ini dan membentuk meme.
Ini adalah kode yang diperbarui untuk komponen
MemeGenerator
. Di sini, dalam metode
render()
, di bawah kode uraian formulir, ada elemen
<div>
, yang mencakup elemen
<img>
yang menampilkan gambar, dan beberapa elemen
<h2>
yang menampilkan label. Elemen
<div>
dan
<h2>
dirancang menggunakan gaya yang kami tambahkan ke proyek pada awal pekerjaan.
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
Seperti apa aplikasi ini sekarang.
Aplikasi di browserPerhatikan fakta bahwa gambar yang menginisialisasi keadaan ditampilkan di sini. Kami belum menggunakan gambar yang disimpan di
allMemeImgs
milik negara. Mari kita coba memasukkan sesuatu ke dalam bidang teks.
Aplikasi di browserSeperti yang Anda lihat, subsistem aplikasi yang bertanggung jawab untuk bekerja dengan teks berfungsi seperti yang diharapkan. Sekarang tinggal memastikan bahwa dengan mengklik tombol
Gen
gambar acak dipilih dari array dengan data gambar dan dimuat ke elemen
<img>
, yang ada pada halaman di bawah bidang input teks.
Untuk melengkapi aplikasi dengan fitur ini - lakukan tugas berikut. Buat metode yang menyala ketika Anda mengklik tombol
Gen
Metode ini harus memilih salah satu gambar yang informasinya disimpan di properti
allMemeImgs
, dan kemudian melakukan tindakan yang memungkinkan Anda untuk menampilkan gambar ini di elemen
<img>
yang terletak di bawah bidang input teks.
allMemeImgs
bahwa
allMemeImgs
menyimpan array objek yang menggambarkan gambar, dan bahwa setiap objek dari array ini memiliki properti
url
.
Berikut adalah kode yang memberikan solusi untuk masalah ini:
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
Tombol
Gen
dapat ditetapkan sebagai pengendali event yang terjadi ketika Anda mengkliknya, seperti halnya dengan tombol lain. Namun, mengingat fakta bahwa tombol ini digunakan untuk mengirimkan formulir, akan lebih baik menggunakan
onSubmit
formulir. Dalam penangan ini,
handleSubmit()
, kami memanggil metode
event.preventDefault()
acara
event.preventDefault()
datang ke dalamnya untuk membatalkan prosedur
event.preventDefault()
formulir standar, di mana halaman tersebut dimuat ulang. Selanjutnya, kita mendapatkan nomor acak dalam rentang dari 0 hingga nilai yang sesuai dengan indeks elemen terakhir dari array
allMemeImgs
dan menggunakan nomor ini untuk merujuk ke elemen dengan indeks yang sesuai. Beralih ke elemen yang merupakan objek, kita mendapatkan properti
url
objek ini dan menulisnya ke properti state
randomImg
. Setelah itu, komponen dirender ulang dan tampilan halaman berubah.
Halaman aplikasi di browserProyek kursus selesai.
Ringkasan
Dalam pelajaran ini, Anda membuat aplikasi yang menggunakan apa yang Anda pelajari saat menguasai Bereaksi. Lain kali kita akan berbicara tentang mengembangkan aplikasi React modern dan mendiskusikan ide-ide proyek, implementasi yang dapat Anda praktikkan bekerja dengan React.
Pembaca yang budiman! Pernahkah Anda mengalami kesulitan saat menyelesaikan proyek kursus ini?