Di bagian penerjemahan kursus Bereaksi hari ini, kami sarankan Anda menyelesaikan tugas praktis berikutnya dan menyajikan kepada Anda sebuah cerita tentang bagaimana mengubah keadaan komponen Bereaksi.

→
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 31. Workshop. Aplikasi TODO. Tahap nomor 5
→
Asli▍ pekerjaan
Saat meluncurkan aplikasi Todo kami, Anda mungkin memperhatikan bahwa pemberitahuan ditampilkan di konsol yang menunjukkan bahwa kami, setelah mengonfigurasi properti yang
checked
dari suatu elemen dalam komponen
TodoItem
, tidak menyediakan mekanisme untuk berinteraksi dengan elemen ini sebagai
onChange
event
onChange
. Ketika bekerja dengan antarmuka aplikasi, ini menghasilkan fakta bahwa bendera yang ditampilkan pada halaman tidak dapat diperiksa atau tidak dicentang.
Di sini Anda diundang untuk melengkapi elemen tipe
checkbox
komponen
TodoItem
dengan pengendali event
TodoItem
, yang, pada tahap kerja ini, cukup untuk disajikan dalam bentuk fungsi yang mengeluarkan sesuatu ke konsol.
OlSolusi
Inilah yang tampak seperti kode komponen
TodoItem
sekarang, yang disimpan dalam file
TodoItem.js
:
import React from "react" function TodoItem(props) { return ( <div className="todo-item"> <input type="checkbox" checked={props.item.completed}/> <p>{props.item.text}</p> </div> ) } export default TodoItem
Inilah yang ditampilkan konsol ketika aplikasi dimulai.
Pemberitahuan konsolPada saat yang sama, bendera tidak merespons efek kami.
Untuk menghilangkan pemberitahuan ini dan menyiapkan proyek untuk pekerjaan lebih lanjut, cukup untuk menetapkan
onChange
acara
onChange
ke elemen
checkbox
. Begini tampilannya dalam kode:
import React from "react" function TodoItem(props) { return ( <div className="todo-item"> <input type="checkbox" checked={props.item.completed} onChange={() => console.log("Changed!")} /> <p>{props.item.text}</p> </div> ) } export default TodoItem
Di sini kita, sebagai penangan, menggunakan fungsi sederhana yang menampilkan kata
Checked!
ke konsol
Checked!
. Pada saat yang sama, mengklik pada bendera tidak menyebabkan perubahan di negara mereka, tetapi pemberitahuan dari konsol, seperti dapat dilihat pada gambar berikut, menghilang.
Bendera masih tidak berfungsi, tetapi pemberitahuan dari konsol menghilangPerubahan kecil yang dilakukan pada aplikasi ini akan memungkinkan kami, setelah kami menangani perubahan status komponen, untuk membuat kotak centang berfungsi dengan benar.
Pelajaran 32. Mengubah Status Komponen
→
AsliMari kita mulai dengan aplikasi standar yang dibuat menggunakan
create-react-app
, di file
App.js
yang berisi kode berikut:
import React from "react" class App extends React.Component { constructor() { super() this.state = { count: 0 } } render() { return ( <div> <h1>{this.state.count}</h1> <button>Change!</button> </div> ) } } export default App
index.css
gaya
index.css
, yang
index.js
dalam file
index.js
, berisi deskripsi gaya berikut:
div { display: flex; flex-direction: column; align-items: center; justify-content: center; } h1 { font-size: 3em; } button { border: 1px solid lightgray; background-color: transparent; padding: 10px; border-radius: 4px; } button:hover { cursor: pointer; } button:focus { outline:0; }
Pada tahap ini, aplikasi tampak seperti yang ditunjukkan pada gambar berikut.
Halaman aplikasi di browserHari ini kita akan berbicara tentang cara mengubah keadaan komponen. Jika komponen memiliki keadaan, ini memungkinkan, dengan menginisialisasi, untuk menyimpan beberapa data di dalamnya. Tetapi jika keadaan tidak dapat diubah, maka komponen tidak akan mendapat banyak manfaat dari keberadaannya, menyimpan data di dalamnya tidak akan jauh berbeda dari, misalnya, menyalinnya dalam kode komponen.
Mari kita bicara tentang aplikasi, pada contoh yang akan kita pertimbangkan bekerja dengan keadaan komponen. Komponen
App
yang kodenya disajikan di atas adalah komponen berbasis kelas. Ini cukup jelas, karena kita membutuhkan komponen ini untuk memiliki keadaan. Dalam kode komponen, kami menggunakan konstruktor.
Di dalamnya, kita, seperti biasa, memanggil metode
super()
dan menginisialisasi keadaan dengan menuliskan properti
count
padanya dan menetapkannya nilai awal
0
. Dalam metode
render()
, kami mencetak tajuk tingkat pertama yang mewakili nilai properti
count
dari keadaan komponen, serta tombol dengan kata
Change!
. Semua ini diformat menggunakan gaya.
Jika, pada tahap pengerjaan aplikasi ini, buka di browser dan klik tombol, maka, tentu saja, tidak ada yang akan terjadi. Tetapi kita perlu mengklik tombol untuk mengubah status komponen, yang mempengaruhi properti
count
. Pada saat yang sama, kami telah mempelajari metodologi pemrosesan acara di Bereaksi, dan tugas kami adalah menciptakan mekanisme yang, menanggapi klik pada tombol, mengubah properti keadaan
count
.
Mari kita mulai untuk memecahkan masalah kita dengan melengkapi tombol dengan
onClick
event
onClick
, yang, sebagai permulaan, hanya akan menampilkan sesuatu ke konsol.
Untuk melakukan ini, kami akan menambahkan metode baru ke kelas komponen. Anda dapat menyebutnya apa saja yang Anda suka, tetapi biasanya memanggil metode tersebut sehingga nama mereka akan menunjukkan peristiwa yang sedang mereka proses. Akibatnya, kami, karena kami akan menggunakannya untuk memproses acara
click
,
handleClick()
. Inilah yang akan terlihat seperti kode komponen
App
.
import React from "react" class App extends React.Component { constructor() { super() this.state = { count: 0 } } handleClick() { console.log("I'm working!") } render() { return ( <div> <h1>{this.state.count}</h1> <button onClick={this.handleClick}>Change!</button> </div> ) } } export default App
Harap perhatikan bahwa merujuk pada metode ini dari
render()
, kami menggunakan konstruksi formulir
this.handleClick
.
Sekarang, jika Anda mengklik tombol, pesan yang sesuai akan muncul di konsol.
Mengklik tombol memanggil metode kelas.Sekarang mari kita membuatnya sehingga mengklik tombol akan meningkatkan angka yang ditampilkan di atasnya, yaitu, memodifikasi keadaan komponen. Mungkin mencoba mengubah keadaan komponen secara langsung, dalam metode
handleClick()
? Katakanlah jika kita menulis ulang metode ini seperti ini:
handleClick() { this.state.count++ }
Saya harus mengatakan segera bahwa ini tidak bekerja dengan keadaan komponen dalam Bereaksi. Mencoba untuk mengeksekusi kode tersebut akan menimbulkan kesalahan.
Kondisi komponen dapat dibandingkan dengan pakaian yang dikenakan seseorang. Jika dia ingin berganti pakaian, dia tidak mengganti atau mengecat ulang pakaian itu tanpa melepas sendiri, tetapi melepasnya dan mengenakan sesuatu yang lain. Faktanya, inilah tepatnya cara mereka bekerja dengan keadaan komponen.
Anda mungkin ingat bahwa kita sedang berbicara tentang metode khusus yang digunakan untuk memodifikasi keadaan, tersedia dalam komponen berdasarkan kelas karena fakta bahwa mereka memperluas kelas
React.Component
. Ini adalah metode
setState()
. Ini digunakan dalam kasus di mana Anda perlu mengubah status komponen. Metode ini dapat digunakan dengan berbagai cara.
Ingatlah bahwa keadaan adalah objek. Mari kita coba meneruskan ke metode
setState()
objek yang akan menggantikan status. Kami menulis ulang metode
handleClick()
ini:
handleClick() { this.setState({ count: 1 }) }
Mencoba menggunakan metode ini akan menyebabkan kesalahan berikut:
TypeError: Cannot read property 'setState' of undefined
. Faktanya, apa yang kita bicarakan sekarang menyebabkan banyak kontroversi di antara para pengembang Bereaksi, dan sekarang saya akan menunjukkan kepada Anda cara yang sangat sederhana untuk menyelesaikan masalah ini, yang, pada pandangan pertama, mungkin tampak tidak biasa.
Intinya adalah bahwa setiap kali, membuat metode kelas (
handleClick()
dalam kasus kami), di mana ia direncanakan untuk menggunakan metode
setState()
, metode ini harus dikaitkan dengan
this
. Ini dilakukan di konstruktor. Kode komponen setelah modifikasi ini akan terlihat seperti ini:
import React from "react" class App extends React.Component { constructor() { super() this.state = { count: 0 } this.handleClick = this.handleClick.bind(this) } handleClick() { this.setState({ count: 1 }) } render() { return ( <div> <h1>{this.state.count}</h1> <button onClick={this.handleClick}>Change!</button> </div> ) } } export default App
Sekarang setelah mengklik tombol
Change!
nomor 1 akan muncul di atasnya, pesan kesalahan tidak akan ditampilkan.
Menekan tombol mengubah keadaanBenar, tombolnya ternyata "satu kali". Setelah klik pertama,
0
berubah menjadi
1
, dan jika Anda mengkliknya lagi, tidak ada yang terjadi. Secara umum, ini tidak mengejutkan. Kode yang dipanggil ketika tombol diklik melakukan tugasnya, setiap kali mengubah negara ke yang baru, namun, setelah klik pertama pada tombol, keadaan baru, di mana nomor
1
disimpan di properti
count
, tidak akan berbeda dari yang lama. Untuk mengatasi masalah ini, pertimbangkan cara lain untuk bekerja dengan metode
setState()
.
Jika kita tidak tertarik dengan keadaan komponen sebelumnya, maka kita bisa meneruskan sebuah objek ke metode ini, yang akan menggantikan keadaan. Tetapi sering terjadi bahwa keadaan baru komponen tergantung pada yang lama. Dalam kasus kami, ini berarti bahwa, berdasarkan nilai properti
count
, yang disimpan di versi negara bagian sebelumnya, kami ingin menambahkan 1 ke nilai ini. Dalam kasus di mana untuk mengubah keadaan Anda perlu mengetahui apa yang sebelumnya disimpan di dalamnya, Anda bisa meneruskan ke metode
setState()
fungsi yang, sebagai parameter, menerima versi negara sebelumnya. Anda dapat memberi nama parameter ini sesuka Anda, dalam kasus kami ini akan
prevState
. Pengadaan fungsi ini akan terlihat seperti ini:
handleClick() { this.setState(prevState => { }) }
Anda mungkin berpikir bahwa dalam fungsi seperti itu cukup dengan merujuk negara menggunakan konstruksi dari form
this.state
, tetapi pendekatan ini tidak cocok untuk kita. Oleh karena itu, fungsi ini penting untuk menerima versi sebelumnya dari status komponen.
Fungsi harus mengembalikan versi baru negara. Inilah yang akan terlihat seperti metode
handleClick()
untuk
handleClick()
masalah ini:
handleClick() { this.setState(prevState => { return { count: prevState.count + 1 } }) }
Perhatikan bahwa untuk mendapatkan nilai baru dari properti
count
, kami menggunakan
count: prevState.count + 1
konstruk. Anda mungkin berpikir bahwa konstruksi
count: prevState.count++
formulir
count: prevState.count++
, tetapi operator
++
count: prevState.count++
variabel yang diterapkannya, ini berarti upaya untuk memodifikasi versi negara bagian sebelumnya, jadi kami tidak menggunakannya di sini.
Kode lengkap file komponen pada tahap ini akan terlihat seperti ini:
import React from "react" class App extends React.Component { constructor() { super() this.state = { count: 0 } this.handleClick = this.handleClick.bind(this) } handleClick() { this.setState(prevState => { return { count: prevState.count + 1 } }) } render() { return ( <div> <h1>{this.state.count}</h1> <button onClick={this.handleClick}>Change!</button> </div> ) } } export default App
Sekarang setiap klik pada tombol meningkatkan nilai penghitung.
Setiap klik pada tombol meningkatkan nilai penghitung.Apa yang baru saja kami temukan membuka peluang besar bagi kami dalam pengembangan aplikasi Bereaksi.
Kami katakan sebelumnya bahwa komponen induk dapat, melalui mekanisme properti, meneruskan properti dari statusnya sendiri ke komponen anak. Jika Bereaksi mendeteksi perubahan dalam status komponen induk, itu akan merender ulang komponen turunan tempat status ini diteruskan. Sepertinya panggilan ke metode
render()
. Akibatnya, komponen anak akan mencerminkan data baru yang disimpan dalam keadaan komponen induk.
Ringkasan
Hari ini Anda telah menyiapkan aplikasi Todo untuk pengerjaan lebih lanjut, dan juga membiasakan diri dengan mekanisme yang digunakan dalam Bereaksi untuk mengubah status komponen. Lain kali Anda akan diminta untuk memperluas kemampuan aplikasi pelatihan menggunakan apa yang Anda pelajari hari ini.
Pembaca yang budiman! Bagaimana perasaan Anda tentang fakta bahwa keadaan komponen dalam Bereaksi tidak dapat diubah secara langsung tanpa menggunakan mekanisme khusus?
