
Hai, habrozhiteli! Edisi asli dirilis pada musim gugur 2017, tetapi masih dianggap sebagai buku terbaik untuk menjelajahi React. Penulis terus memperbarui dan memodifikasi kode untuk buku di repositori
Github .
Kami menyarankan dalam posting untuk berkenalan dengan bagian "Serikat dan peran mereka dalam sifat interaktif React"
Jika Anda harus membaca hanya satu bab dalam buku ini, Anda harus memilih yang ini! Tanpa status, komponen Bereaksi tetap tidak lebih dari pola statis lanjut. Saya harap Anda berbagi antusiasme saya karena memahami konsep-konsep dalam bab ini akan memungkinkan Anda untuk membangun aplikasi yang jauh lebih menarik.
Bayangkan Anda sedang membangun bidang input dengan pelengkapan otomatis (Gbr. 4.1). Saat memasukkan data, bidang harus mengeluarkan permintaan ke server untuk mendapatkan informasi tentang opsi yang sesuai untuk menampilkan output di halaman web. Anda telah bekerja dengan properti sejauh ini, dan Anda tahu bahwa mengubah properti memungkinkan Anda untuk mendapatkan tampilan berbeda. Namun, properti tidak dapat diubah dalam konteks komponen saat ini, karena mereka dilewatkan ketika komponen dibuat.

Dengan kata lain, properti tidak dapat diubah dalam komponen saat ini, yang berarti bahwa Anda tidak dapat mengubah properti di komponen ini kecuali jika Anda membuat ulang komponen dan mentransfer nilai baru dari induknya (Gbr. 4.2). Tetapi informasi yang diterima dari server perlu disimpan di suatu tempat, dan kemudian daftar opsi baru harus ditampilkan dalam tampilan. Bagaimana cara memperbarui tampilan jika properti tidak dapat diubah?
Salah satu solusi yang mungkin adalah membuat elemen dengan properti baru setiap kali Anda menerima respons baru dari server. Tetapi kemudian Anda harus menempatkan logika di luar komponen - dan komponen berhenti mandiri. Jelas, jika nilai properti tidak dapat diubah, dan pelengkapan otomatis harus mandiri, tidak mungkin untuk menggunakan properti. Kemudian muncul pertanyaan: bagaimana cara memperbarui tampilan dalam menanggapi peristiwa tanpa membuat ulang komponen (createElement () atau JSX <NAME />)? Inilah masalah yang dipecahkan negara bagian.
Setelah respons dari server siap, kode panggilan balik akan mengubah status komponen yang sesuai. Anda harus menulis kode ini sendiri. Namun, setelah negara diperbarui, Bereaksi akan secara otomatis memperbarui tampilan untuk Anda (hanya di tempat-tempat di mana harus diperbarui, yaitu, di mana data negara digunakan).
Dengan status komponen Bereaksi, Anda dapat membuat aplikasi Bereaksi yang interaktif dan bermakna. Status adalah konsep dasar yang memungkinkan Anda membangun komponen Bereaksi yang dapat menyimpan data dan memperbarui tampilan secara otomatis sesuai dengan perubahan data.
Bagaimana keadaan komponen Bereaksi?
Keadaan Bereaksi adalah penyimpanan data komponen yang dapat diubah - blok berorientasi fungsi yang berdiri sendiri dari antarmuka pengguna dan logika. "Variabilitas" berarti bahwa nilai status dapat berubah. Dengan menggunakan status dalam tampilan (render ()) dan mengubah nilai nanti, Anda dapat memengaruhi tampilan tampilan.
Metafora: jika Anda membayangkan komponen dalam bentuk fungsi, ke input yang properti dan negara ditransmisikan, hasil dari fungsi akan menjadi deskripsi antarmuka pengguna (presentasi). Properti dan status memperluas tampilan, tetapi digunakan untuk tujuan yang berbeda (lihat bagian 4.3).
Saat bekerja dengan negara, Anda mengaksesnya dengan nama. Nama adalah atribut (yaitu, kunci objek atau properti objek - bukan properti komponen) objek this.state, misalnya this.state.autocompleMatches atau this.state.inputFieldValue.
Status data sering digunakan untuk menampilkan informasi dinamis dalam tampilan untuk memperluas rendering tampilan. Kembali ke contoh sebelumnya dari bidang autocomplete: status berubah sebagai respons terhadap permintaan XHR ke server, yang, pada gilirannya, dimulai dengan memasukkan data ke dalam bidang. Bereaksi memastikan bahwa tampilan diperbarui ketika keadaan yang digunakan dalam perubahan tampilan. Bahkan, ketika keadaan berubah, hanya bagian yang sesuai dari representasi yang berubah (ke elemen individual dan bahkan nilai atribut dari elemen individual).
Segala sesuatu yang lain di DOM tetap tidak berubah. Ini dimungkinkan berkat model DOM virtual (lihat bagian 1.1.1), yang Bereaksi gunakan untuk menentukan delta (totalitas perubahan) selama proses rekonsiliasi. Fakta ini memungkinkan Anda untuk menulis kode dengan gaya deklaratif. Bereaksi melakukan semua rutin untuk Anda. Tahapan utama untuk mengubah presentasi dibahas di Bab 5.
Bereaksi pengembang menggunakan status untuk menghasilkan antarmuka pengguna baru. Properti komponen (this.props), variabel biasa (inputValue) dan atribut kelas (this.inputValue) tidak cocok untuk ini, karena mengubah nilainya (dalam konteks komponen saat ini) tidak memicu perubahan dalam tampilan. Misalnya, cuplikan berikut ini adalah antipattern, yang menunjukkan bahwa mengubah nilai di mana pun kecuali keadaan tidak akan menyebabkan tampilan menyegarkan:
// : ! let inputValue = 'Texas' class Autocomplete extends React.Component { updateValues() β { ( ) this.props.inputValue = 'California' inputValue = 'California' this.inputValue = 'California' } render() { return ( <div> {this.props.inputValue} {inputValue} {this.inputValue} </div> ) } }
Sekarang mari kita lihat bagaimana cara bekerja dengan keadaan komponen Bereaksi.
Bekerja dengan negara
Untuk bekerja dengan status, Anda harus dapat mengakses nilai, memperbaruinya, dan menetapkan nilai awal. Mari kita mulai dengan merujuk pada status dalam komponen Bereaksi.
Akses ke negara
Objek status adalah atribut komponen, dan Anda harus mengaksesnya melalui tautan ini, misalnya this.state.name. Seperti yang Anda ingat, variabel dapat diakses dan ditampilkan dalam kode JSX dalam kurung kurawal ({}). Demikian pula, dalam render (), Anda dapat membuat ini.state (seperti atribut variabel atau kelas lainnya dari komponen non-standar), misalnya {this.state.inputFieldValue}. Sintaks ini mirip dengan sintaks untuk mengakses properti di this.props.name.

Kami menggunakan apa yang Anda pelajari untuk mengimplementasikan jam dalam gambar. 4.3. Tujuan kami adalah membuat kelas komponen otonom yang dapat diimpor dan digunakan siapa pun dalam aplikasi mereka tanpa banyak kesulitan. Jam harus menampilkan waktu saat ini.
Proyek ini memiliki struktur sebagai berikut:
/clock index.html /jsx script.jsx clock.jsx /js script.js clock.js react.js react-dom.js
Saya menggunakan Babel CLI dengan flag pelacakan (-w) dan direktori (-d) untuk mengkompilasi semua file sumber JSX dari clock / jsx ke folder target jam / js dan mengkompilasi ulang ketika perubahan terdeteksi. Selain itu, saya menyimpan perintah sebagai skrip npm di file package.json dari folder induk ch04 untuk mengeksekusi perintah run-jam npm run dari ch04:
"scripts": { "build-clock": "./node_modules/.bin/babel clock/jsx -d clock/js -w" },
Tentu saja, waktu tidak berhenti (apakah kita suka atau tidak). Karena itu, Anda harus terus memperbarui tampilan, dan untuk ini Anda dapat menggunakan negara. Beri nama currentTime dan coba render status seperti yang ditunjukkan pada Listing 4.1.
Daftar 4.1. Render keadaan BEJ
class Clock extends React.Component { render() { return <div>{this.state.currentTime}</div> } } ReactDOM.render( <Clock />, document.getElementById('content') )
Anda akan menerima pesan kesalahan: UnEught TypeError: Tidak dapat membaca properti 'currentTime' dari nol. Biasanya pesan kesalahan JavaScript memiliki manfaat yang sama dengan segelas air dingin untuk orang yang tenggelam. Sangat bagus bahwa setidaknya dalam kasus ini, JavaScript menampilkan pesan yang bermakna.
Pesan tersebut menunjukkan bahwa nilai currentTime tidak terdefinisi. Tidak seperti properti, status tidak disetel pada induk. Memanggil setState di render () juga gagal, karena itu akan membuat loop (setState -> render -> setState ...) - dan Bereaksi akan melaporkan kesalahan.
Penugasan keadaan awal
Anda telah melihat bahwa sebelum menggunakan data status di render (), Anda harus menginisialisasi status. Untuk mengatur keadaan awal, gunakan status ini dalam konstruktor dengan sintaks kelas ES6 React.Component. Ingatlah untuk memanggil super () dengan properti; jika tidak, logika di induk (React.Component) tidak akan berfungsi:
class MyFancyComponent extends React.Component { constructor(props) { super(props) this.state = {...} } render() { ... } }
Saat menetapkan keadaan awal, Anda juga dapat menambahkan logika lain - misalnya, atur nilai currentTime menggunakan Date baru (). Anda bahkan dapat menggunakan toLocaleString () untuk mendapatkan format tanggal / waktu yang benar untuk lokasi pengguna saat ini, seperti yang ditunjukkan di bawah ini (ch04 / jam).
Listing 4.2. Konstruktor komponen jam
class Clock extends React.Component { constructor(props) { super(props) this.state = {currentTime: (new Date()).toLocaleString()} } ... }
Nilai this.state harus berupa objek. Kami tidak akan membahas detail konstruktor () dari ES6; lihat Lampiran D dan Ringkasan
ES6 di
github.com/azat-co/cheatsheets/tree/master/es6 . Intinya adalah bahwa, seperti dalam bahasa OOP lainnya, sebuah konstruktor (yaitu konstruktor ()) dipanggil ketika instance kelas dibuat. Nama metode konstruktor harus hanya itu; pertimbangkan ini salah satu aturan ES6. Selain itu, saat membuat metode konstruktor (), panggilan super () hampir selalu disertakan di dalamnya, tanpanya, konstruktor induk tidak akan dieksekusi. Di sisi lain, jika Anda tidak mendefinisikan metode constructor (), maka panggilan ke super () akan dianggap secara default.
Nama currentTime adalah opsional; Anda harus menggunakan nama yang sama nanti ketika membaca dan memperbarui keadaan ini.
Objek keadaan dapat berisi objek atau array bersarang. Contoh berikut menambahkan array deskripsi buku ke keadaan:
class Content extends React.Component { constructor(props) { super(props) this.state = { githubName: 'azat-co', books: [ 'pro express.js', 'practical node.js', 'rapid prototyping with js' ] } } render() { ... } }
Metode constructor () dipanggil hanya sekali, ketika membuat elemen Bereaksi berdasarkan kelas. Dengan demikian, Anda dapat mengatur negara secara langsung menggunakan this.state hanya sekali - dalam metode constructor (). Jangan mengatur atau memperbarui negara secara langsung dengan this.state = ... di tempat lain, karena ini dapat menyebabkan konsekuensi yang tidak terduga.
Jadi Anda hanya mendapatkan nilai awal, yang dengan cepat akan menjadi usang - hanya dalam 1 detik. Siapa yang butuh arloji yang tidak menunjukkan waktu saat ini? Untungnya, ada mekanisme untuk memperbarui keadaan saat ini.
Pembaruan status
Status diubah dengan metode kelas this.setState (data, callback). Ketika metode ini dipanggil, Bereaksi menggabungkan data dengan status saat ini dan panggilan render (), setelah itu ia memanggil panggilan balik.
Mendefinisikan callback callback di setState () penting karena metode ini bekerja secara tidak sinkron. Jika aplikasi tergantung pada status baru, Anda dapat menggunakan panggilan balik ini untuk memastikan bahwa status baru telah tersedia.
Jika Anda hanya berasumsi bahwa negara telah diperbarui tanpa menunggu setState () selesai, yaitu bekerja secara serempak saat melakukan operasi asinkron, kesalahan dapat terjadi: program bergantung pada pemutakhiran nilai status, tetapi keadaan tetap lama.
Sejauh ini, kami telah memberikan waktu dari negara. Anda sudah tahu cara mengatur keadaan awal, tetapi harus diperbarui setiap detik, bukan? Untuk melakukan ini, gunakan fungsi pengatur waktu browser setInterval () (http://mng.bz/P2d6), yang akan memperbarui status setiap n milidetik. Metode setInterval () diimplementasikan di hampir semua browser modern sebagai global, yang berarti dapat digunakan tanpa pustaka atau awalan tambahan. Contoh:
setInterval(()=>{ console.log('Updating time...') this.setState({ currentTime: (new Date()).toLocaleString() }) }, 1000)
Untuk memulai hitungan mundur, Anda perlu memanggil setInterval () hanya sekali. Kami membuat metode launchClock () hanya untuk tujuan ini; launchClock () akan dipanggil di konstruktor. Versi terakhir dari komponen ini ditunjukkan pada Listing 4.3 (ch04 / clock / jsx / clock.jsx).
Metode setState () dapat dipanggil di mana saja, tidak hanya dalam metode launchClock () (yang disebut dalam konstruktor), seperti pada contoh. Biasanya, metode setState () dipanggil dari event handler atau sebagai panggilan balik ketika data diterima atau diperbarui.
TIP Upaya mengubah status dalam kode dengan perintah dari formulir this.state.name = 'nama baru' tidak akan menghasilkan apa pun. Ini tidak akan menyebabkan rendering ulang dan memperbarui model DOM yang sebenarnya, apa yang Anda inginkan. Dalam sebagian besar kasus, perubahan status langsung tanpa setState () bersifat antipattern dan harus dihindari.
Penting untuk dicatat bahwa metode setState () hanya memutakhirkan status yang diteruskan (sebagian atau digabung, tetapi tanpa penggantian yang lengkap). Itu tidak mengganti seluruh objek negara setiap waktu. Oleh karena itu, jika hanya satu dari tiga negara telah berubah, dua lainnya akan tetap tidak berubah. Dalam contoh berikut, userEmail dan userId tidak akan berubah:
constructor(props) { super(props) this.state = { userName: 'Azat Mardan', userEmail: 'hi@azat.co', userId: 3967 } } updateValues() { this.setState({userName: 'Azat'}) }
Jika Anda bermaksud memperbarui ketiga status, Anda harus melakukan ini secara eksplisit dengan meneruskan nilai baru dari status ini ke setState (). (Juga dalam kode lama, yang sekarang tidak lagi berfungsi, metode this.replaceState () kadang-kadang ditemukan; secara resmi tidak digunakan 1. Seperti yang Anda tebak dengan namanya, ia mengganti seluruh objek keadaan dengan semua atributnya.)
Ingat bahwa memanggil setState () memulai eksekusi render (). Dalam kebanyakan kasus, ini berfungsi. Dalam beberapa kasus khusus di mana kode tergantung pada data eksternal, Anda dapat memulai render dengan memanggil this.forceUpdate (). Namun demikian, keputusan seperti itu tidak diinginkan, karena mengandalkan data eksternal (bukan negara) membuat komponen kurang dapat diandalkan dan tergantung pada faktor-faktor eksternal (ikatan ketat).
Seperti yang disebutkan sebelumnya, objek keadaan dapat diakses di entri this.state. Di BEJ, nilai-nilai output terlampir dalam kurung kurawal ({}), oleh karena itu, untuk menyatakan properti negara dalam tampilan (yaitu, dalam perintah pengembalian metode render), gunakan notasi {this.state.NAME}.
Bereaksi ajaib terjadi ketika Anda menggunakan data status dalam tampilan (misalnya, dalam output, dalam perintah if / else, sebagai nilai atribut atau nilai properti anak), lalu meneruskan setState () nilai baru. Bah! Bereaksi pembaruan semua markup HTML yang diperlukan untuk Anda. Anda dapat memverifikasi ini di konsol DevTools, di mana siklus "Memperbarui ..." dan "Rendering ..." harus ditampilkan. Dan hal yang hebat adalah bahwa ini hanya akan mempengaruhi elemen DOM minimum absolut yang diperlukan.
Β»Informasi lebih lanjut tentang buku ini dapat ditemukan di
situs web penerbitΒ»
IsiΒ»
KutipanKupon diskon 20% untuk penjaja -
BereaksiSetelah pembayaran versi kertas buku, versi elektronik buku dikirim melalui email.