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 Headeryang 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 randomImageyang 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?