React Tutorial Bagian 25: Workshop tentang Formulir

Di bagian penerjemahan kursus pelatihan Bereaksi hari ini, Anda diundang untuk menyelesaikan tugas formulir.

gambar

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 komponen
Bagian 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 kursus

Pelajaran 43. Workshop. Bekerja dengan formulir


Asli

▍ pekerjaan


Dalam pelajaran praktis ini, Anda diundang untuk membuka kode komponen App , yang terletak di file App.js dari proyek standar yang dibuat oleh create-react-app. Ini kodenya:

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {}   }     render() {       return (           <main>               <form>                   <input placeholder="First Name" /><br />                   <input placeholder="Last Name" /><br />                   <input placeholder="Age" /><br />                                     {/*       */}                   <br />                                     {/*          */}                   <br />                                     {/*        */}                   <br />                                     <button>Submit</button>               </form>               <hr />               <h2><font color="#3AC1EF">Entered information:</font></h2>               <p>Your name: {/*    */}</p>               <p>Your age: {/*  */}</p>               <p>Your gender: {/*  */}</p>               <p>Your destination: {/*   */}</p>               <p>                   Your dietary restrictions:                   {/*    */}               </p>           </main>       )   } } export default App 

Secara umum, tugas Anda adalah memastikan bahwa data yang dimasukkan pengguna saat bekerja dengan kontrol formulir segera muncul dalam teks di bawah formulir ini. Manfaatkan teknologi komponen terkelola saat Anda menyelesaikan tugas. Perlu dicatat bahwa tugas yang ditawarkan kepada Anda adalah versi yang disesuaikan dari tugas ini , sehingga Anda dapat melihatnya untuk lebih memahami fitur-fitur kontrol yang Anda undang untuk buat dan konfigurasi.

Inilah komponen yang sekarang ditampilkan di layar.


Aplikasi di browser

OlSolusi


Anda dapat mendekati solusi dari masalah yang diajukan kepada Anda dari berbagai sudut. Kami akan mulai dengan memasukkan semua yang kami butuhkan ke dalam status, setelah itu kami akan mengatur kontrol dan mekanisme komponen lainnya.

Saat ini, keadaan komponen akan terlihat seperti yang ditunjukkan di bawah ini.

 this.state = {   firstName: "",   lastName: "",   age: 0,   gender: "",   destination: "",   dietaryRestrictions: [] } 

Harus diingat bahwa dalam proses mengerjakan suatu program mungkin ternyata, sebagai contoh, akan lebih mudah untuk menginisialisasi keadaan secara berbeda. Jika kita mengalami sesuatu yang serupa, kita akan mengubah kode inisialisasi negara. Khususnya, sekarang beberapa keraguan mungkin disebabkan oleh angka 0 yang tertulis di properti age , di mana ia seharusnya menyimpan usia yang dimasukkan oleh pengguna. Mungkin, perlu dilakukan sebaliknya dengan sistem penyimpanan data flag, yang sekarang diwakili oleh properti dietaryRestrictions , diinisialisasi dengan array kosong.

Sekarang, setelah inisialisasi keadaan, kita akan mengambil konfigurasi kontrol. Karena kode sudah memiliki deskripsi bidang input - mari kita mulai dengan mereka.

Kontrol ini perlu diberi nama dengan mengatur atribut name mereka sehingga mereka cocok dengan nama properti negara di mana data yang dimasukkan ke dalam bidang ini akan disimpan. Mereka harus memiliki atribut value yang nilainya ditentukan berdasarkan data yang disimpan di negara bagian. Saat memasukkan data ke masing-masing bidang ini, Anda harus meneruskan data yang dimasukkan ke komponen, yang mengarah pada kebutuhan mereka untuk memiliki onChange event onChange . Semua pertimbangan ini mengarah pada fakta bahwa deskripsi bidang sekarang terlihat seperti ini:

 <input   name="firstName"   value={this.state.firstName}   onChange={this.handleChange}   placeholder="First Name" /> <br /> <input   name="lastName"   value={this.state.lastName}   onChange={this.handleChange}   placeholder="Last Name" /> <br /> <input   name="age"   value={this.state.age}   onChange={this.handleChange}   placeholder="Age" /> 

Sebagai metode yang digunakan untuk memproses peristiwa onChange bidang ini, this.handleChange masih tidak ada. Buat metode ini:

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

Di sini kita mengekstrak properti name dan value dari objek event.target , dan kemudian menggunakannya untuk mengatur properti negara terkait. Saat ini, kode event handler universal akan cocok untuk kita, tetapi kemudian, ketika kita mulai bekerja dengan flag, kita akan melakukan perubahan padanya.

Jangan lupa tentang pengikatan this dilakukan di konstruktor komponen:

 this.handleChange = this.handleChange.bind(this) 

Untuk mencapai output di bagian bawah halaman data yang dimasukkan di bidang firstName , secondName , dan age , secondName akan bekerja dengan elemen <p> sesuai, membawanya ke formulir berikut:

 <p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p> 

Sekarang mari kita lihat apa yang kita dapat.


Aplikasi di browser

Seperti yang Anda lihat, di bidang untuk memasukkan usia, petunjuk tidak ditampilkan. Alih-alih, apa yang diatur dalam properti state of age ditampilkan, yaitu 0. Kita perlu petunjuk di bidang kosong. Mari kita coba ganti nilai age dalam keadaan dengan null . Setelah itu, ternyata formulir itu terlihat sebagaimana mestinya, tetapi peringatan berikut ini ditampilkan di konsol mengenai bidang age :

 Warning: `value` prop on `input` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components 

Sebagai hasilnya, kita perlu mengganti nilai properti state age dengan string kosong, membawa kode inisialisasi state ke form berikut:

 this.state = {   firstName: "",   lastName: "",   age: "",   gender: "",   destination: "",   dietaryRestrictions: [] } 

Sekarang coba formulirnya. Segera setelah pembukaan, itu akan terlihat sama seperti pada awal pekerjaan, yaitu, prompt akan kembali ke bidang age . Saat mengisi kolom, data yang dimasukkan akan ditampilkan di bagian bawah halaman.


Aplikasi di browser

Seperti yang Anda lihat, pada tahap pekerjaan ini, semuanya berfungsi seperti yang diharapkan.

Sekarang kita akan terlibat dalam elemen baru. Langkah selanjutnya dalam mengerjakan formulir adalah menambahkan sakelar ke dalamnya.

Bungkus sakelar dalam <label> , yang akan memungkinkan kita tidak hanya menandatangani sakelar, tetapi juga memastikan bahwa mengklik tanda tangan ini, yaitu, pada elemen induknya, mengarah ke pemilihannya.

Saat bekerja dengan sakelar, perlu diingat bahwa itu adalah semacam kombinasi flag dengan atribut yang checked dan bidang teks yang memiliki atribut value . Sakelar membentuk grup yang masing-masing sakelar diberi nama yang sama, dan properti yang checked sakelar diatur sesuai dengan kondisi yang dikonfigurasikan sehingga tidak mungkin untuk menghidupkan lebih dari satu sakelar yang merupakan bagian dari grup yang sama. onChange sebagai pengendali acara untuk sakelar onChange .

Akibatnya, kode deskripsi sakelar akan terlihat seperti ini:

 <label>   <input       type="radio"       name="gender"       value="male"       checked={this.state.gender === "male"}       onChange={this.handleChange}   /> Male </label> <br /> <label>   <input       type="radio"       name="gender"       value="female"       checked={this.state.gender === "female"}       onChange={this.handleChange}   /> Female </label> 

Sekarang kita akan memproses elemen <p> yang terletak di bagian bawah halaman, sebagai berikut:

 <p>Your gender: {this.state.gender}</p> 

Setelah itu, formulir dapat diuji. Segera setelah memulai, kedua sakelar tidak dipilih, karena keadaan disimpan dalam nilai yang tidak memungkinkan pemeriksaan yang dilakukan saat mengatur properti yang checked untuk checked true . Setelah mengklik salah satu dari mereka, nilai yang sesuai jatuh ke keadaan (disimpan dalam atribut nilai switch), saklar dipilih, teks yang sesuai ditampilkan di bagian bawah formulir.


Aplikasi di browser

Sekarang mari kita bekerja pada kotak kombo. Benda kerjanya terlihat seperti ini:

 <select>   <option></option>   <option></option>   <option></option>   <option></option> </select> 

Kode ini menunjukkan bahwa kami berencana untuk menggambarkan kotak kombo yang berisi empat item.

Tag <select> dan tag <option> -nya memiliki atribut value . Namun, atribut ini memiliki arti yang berbeda. Nilai value ditetapkan untuk elemen <option> menunjukkan apa yang seharusnya menjadi properti negara terkait ketika elemen ini dipilih. Ini adalah garis yang harus ada dalam daftar drop-down. Dalam kasus kami, ini adalah tujuan tertentu, misalnya, negara. Mari kita menulis nama mereka dengan huruf kecil sehingga penampilan mereka akan sesuai dengan value properti value elemen lain dalam kode. Setelah itu, kode untuk kotak kombo akan terlihat seperti ini:

 <select value=>   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select> 

Jika kita berbicara tentang atribut value dari <select> , maka tidak beberapa nilai kode-keras akan ditunjukkan di sini, tetapi tautan ke properti state terkait:

 <select value={this.state.destination}>   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select> 

Tetapkan bidang atribut lainnya. Secara khusus, nama yang sesuai dengan nama properti di negara bagian, dan onChange event this.handleChange , this.handleChange .

 <select   value={this.state.destination}   name="destination"   onChange={this.handleChange} >   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select> 

Sekarang kami akan mengonfigurasi uraian elemen <p> , yang akan menampilkan apa yang dipilih di bidang destination :

 <p>Your destination: {this.state.destination}</p> 

Jika Anda melihat halaman di browser sekarang, Anda dapat melihat bahwa elemen pertama dari daftar secara otomatis dipilih di bidang, tetapi ini jelas tidak mengarah pada pembaruan negara, karena tidak ada yang ditampilkan setelah titik dua di titik Your destination: baris.


Aplikasi di browser

Agar nilai germany jatuh ke negara bagian, Anda harus membuka kotak kombo dan pertama memilih sesuatu yang lain, lalu pilih Germany .

Seringkali, untuk mempertimbangkan fitur bidang daftar ini, dalam daftar mereka, sebagai elemen pertama, mereka meletakkan sesuatu seperti elemen dengan nilai kosong dan dengan teks seperti -- Please Choose a destination -- . Dalam kasus kami, ini mungkin terlihat seperti ini:

 <select   value={this.state.destination}   name="destination"   onChange={this.handleChange} >   <option value="">-- Please Choose a destination --</option>   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select> 

Kami akan fokus pada opsi pengaturan kotak kombo ini.

Sekarang mari kita berurusan dengan, mungkin, bagian paling sulit dari tugas kita, yang terkait dengan bendera. Di sini perlu dietaryRestrictions bahwa dietaryRestrictions properti negara, yang rencananya akan digunakan untuk bekerja dengan bendera, diinisialisasi dengan array kosong. Sekarang, ketika datang untuk bekerja dengan kontrol, ada perasaan bahwa akan lebih baik untuk mewakili bidang ini sebagai objek. Jadi akan lebih nyaman untuk bekerja dengan entitas yang mewakili bendera individu dalam bentuk properti objek ini dengan nama yang bersahabat, dan bukan dalam bentuk elemen array. Properti objek, yang sekarang akan diwakili oleh dietaryRestrictions status dietaryRestrictions , akan berisi nilai boolean yang menunjukkan apakah kotak centang yang sesuai dihapus ( false ) atau dicentang ( true ). Sekarang kode inisialisasi negara akan terlihat seperti ini:

 this.state = {   firstName: "",   lastName: "",   age: "",   gender: "",   destination: "",   dietaryRestrictions: {       isVegan: false,       isKosher: false,       isLactoseFree: false   } } 

Seperti yang Anda lihat, kami berencana untuk membuat tiga bendera. Semuanya, segera setelah memuat halaman, akan diatur ulang.

Kami menjelaskan flag dalam kode yang dikembalikan oleh komponen, membungkusnya dalam <label> dan mengatur atributnya. Di sini akan terlihat seperti apa kode mereka:

 <label>   <input       type="checkbox"       name="isVegan"       onChange={this.handleChange}       checked={this.state.dietaryRestrictions.isVegan}   /> Vegan? </label> <br /> <label>   <input       type="checkbox"       name="isKosher"       onChange={this.handleChange}       checked={this.state.dietaryRestrictions.isKosher}   /> Kosher? </label> <br /> <label>   <input       type="checkbox"       name="isLactoseFree"       onChange={this.handleChange}       checked={this.state.dietaryRestrictions.isLactoseFree}   /> Lactose Free? </label> 

Nama-nama flag yang digunakan adalah nama properti dari objek dietaryRestrictions , dan nilai atribut yang checked adalah konstruksi dari form this.state.dietaryRestrictions.isSomething .

Harap dicatat bahwa, meskipun onChange ada ditetapkan sebagai penangan event this.handleChange , kami harus membuat beberapa perubahan pada program untuk memastikan bahwa program bekerja dengan benar.

Lihatlah aplikasinya.


Aplikasi di browser

Seperti yang Anda lihat, bendera pada halaman ditampilkan, tetapi komponennya belum memuat semua mekanisme yang diperlukan untuk memastikan operasi yang benar. Mari kita berurusan dengan event handler.

Di sini, untuk bekerja dengan kotak centang, kita perlu mengekstrak event.target dari objek, selain yang sudah diekstraksi, type dan properti yang checked . Yang pertama diperlukan untuk memeriksa jenis elemen (bendera adalah tipe yang diwakili oleh garis checkbox ), yang kedua adalah untuk mengetahui apakah kotak centang dicentang atau tidak dicentang. Jika ternyata pawang dipanggil setelah pengguna berinteraksi dengan bendera, kami menggunakan prosedur pengaturan keadaan khusus. Kami akan menangani peristiwa kontrol lain dengan cara yang sama seperti sebelumnya.

Ketika memperbarui negara, harus diingat bahwa Bereaksi adalah sistem yang cukup cerdas yang, jika hanya bagian dari negara yang diperbarui, secara otomatis akan bergabung dalam keadaan baru apa yang tetap tidak berubah dengan apa yang telah berubah. Tetapi orang tidak dapat memastikan bahwa pekerjaan dengan properti benda, yang merupakan nilai dari properti negara, akan dilakukan dengan cara yang sama. Kami akan memverifikasi ini dengan membawa kode handleChange ke formulir berikut. Di sini kita melanjutkan dari asumsi bahwa sifat-sifat objek dietaryRestrictions dapat diubah satu per satu:

 handleChange(event) {   const {name, value, type, checked} = event.target   type === "checkbox" ?       this.setState({           dietaryRestrictions: {               [name]: checked           }       })   :   this.setState({       [name]: value   }) } 

Jika Anda membuka halaman aplikasi di browser, maka segera setelah mengunduhnya, semuanya akan terlihat baik, ketika Anda mencoba, misalnya, untuk memasukkan nama di bidang First Name Depan, semuanya juga akan berfungsi seperti sebelumnya, tetapi ketika Anda mencoba mengatur salah satu kotak centang, peringatan berikut akan dikeluarkan :
Peringatan: Komponen mengubah input terkontrol dari kotak centang tipe menjadi tidak terkontrol. Elemen input tidak boleh beralih dari dikontrol ke tidak terkontrol (atau sebaliknya). Putuskan antara menggunakan elemen input yang dikontrol atau tidak dikontrol selama masa pakai komponen. Info lebih lanjut: fb.me/react-controlled-components

Untuk memperbarui konten objek dietaryRestrictions dengan dietaryRestrictions , Anda dapat menggunakan formulir fungsional setState untuk membuat versi baru dari kondisi Anda sendiri. Jika kita harus mengelola sejumlah besar bendera, maka mungkin kita akan melakukannya. Tetapi di sini kita akan melakukan sebaliknya. Yaitu, kita akan membuat properti dari properti dietaryRestrictions objek dietaryRestrictions , menyingkirkan objek ini:

 this.state = {   firstName: "",   lastName: "",   age: "",   gender: "",   destination: "",   isVegan: false,   isKosher: false,   isLactoseFree: false } 

Sekarang kita akan mengubah pengaturan atribut bendera, menghilangkan dietaryRestrictions :

 <label>   <input       type="checkbox"       name="isVegan"       onChange={this.handleChange}       checked={this.state.isVegan}   /> Vegan? </label> <br /> <label>   <input       type="checkbox"       name="isKosher"       onChange={this.handleChange}       checked={this.state.isKosher}   /> Kosher? </label> <br /> <label>   <input       type="checkbox"       name="isLactoseFree"       onChange={this.handleChange}       checked={this.state.isLactoseFree}   /> Lactose Free? </label> 

Dan akhirnya, edit kode elemen yang menampilkan informasi tentang batasan diet yang ditentukan oleh pengguna:

 <p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p> 

Setelah itu, kami akan memeriksa kesehatan aplikasi.


Aplikasi di browser

Seperti yang Anda lihat, semuanya berfungsi seperti yang diharapkan.

Berikut ini adalah kode lengkap komponen App :

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {           firstName: "",           lastName: "",           age: "",           gender: "",           destination: "",           isVegan: false,           isKosher: false,           isLactoseFree: false       }       this.handleChange = this.handleChange.bind(this)   }     handleChange(event) {       const {name, value, type, checked} = event.target       type === "checkbox" ?           this.setState({               [name]: checked           })       :       this.setState({           [name]: value       })   }     render() {       return (           <main>               <form>                   <input                       name="firstName"                       value={this.state.firstName}                       onChange={this.handleChange}                       placeholder="First Name"                   />                   <br />                                     <input                       name="lastName"                       value={this.state.lastName}                       onChange={this.handleChange}                       placeholder="Last Name"                   />                   <br />                                     <input                       name="age"                       value={this.state.age}                       onChange={this.handleChange}                       placeholder="Age"                   />                   <br />                                     <label>                       <input                           type="radio"                           name="gender"                           value="male"                           checked={this.state.gender === "male"}                           onChange={this.handleChange}                       /> Male                   </label>                                     <br />                                     <label>                       <input                           type="radio"                           name="gender"                           value="female"                           checked={this.state.gender === "female"}                           onChange={this.handleChange}                       /> Female                   </label>                                     <br />                                     <select                       value={this.state.destination}                       name="destination"                       onChange={this.handleChange}                   >                       <option value="">-- Please Choose a destination --</option>                       <option value="germany">Germany</option>                       <option value="norway">Norway</option>                       <option value="north pole">North Pole</option>                       <option value="south pole">South Pole</option>                   </select>                                     <br />                                     <label>                       <input                           type="checkbox"                           name="isVegan"                           onChange={this.handleChange}                           checked={this.state.isVegan}                       /> Vegan?                   </label>                   <br />                                     <label>                       <input                           type="checkbox"                           name="isKosher"                           onChange={this.handleChange}                           checked={this.state.isKosher}                       /> Kosher?                   </label>                   <br />                                     <label>                       <input                           type="checkbox"                           name="isLactoseFree"                           onChange={this.handleChange}                           checked={this.state.isLactoseFree}                       /> Lactose Free?                   </label>                   <br />                                     <button>Submit</button>               </form>               <hr />               <h2><font color="#3AC1EF">Entered information:</font></h2>               <p>Your name: {this.state.firstName} {this.state.lastName}</p>               <p>Your age: {this.state.age}</p>               <p>Your gender: {this.state.gender}</p>               <p>Your destination: {this.state.destination}</p>               <p>Your dietary restrictions:</p>                             <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p>               <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p>               <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p>                         </main>       )   } } export default App 

Ringkasan


Hari ini Anda telah menyelesaikan pekerjaan praktis pada formulir. Kemudian Anda mengulangi apa yang Anda pelajari di kelas sebelumnya, dan kami harap Anda mempelajari sesuatu yang baru. Lain kali kita akan berbicara tentang arsitektur aplikasi Bereaksi.

Pembaca yang budiman! Katakan padaku, apakah sulit untuk menyelesaikan pekerjaan praktis ini?

Source: https://habr.com/ru/post/id446208/


All Articles