React.js: A Beginner's Guide

Penulis artikel, terjemahan yang kami terbitkan, percaya bahwa, sayangnya, sebagian besar panduan Bereaksi yang ada tidak memperhatikan teknik pengembangan praktis yang berharga. Panduan ini tidak selalu memberi orang yang terlibat di dalamnya pemahaman tentang apa "pendekatan yang tepat" untuk bekerja dengan React.

gambar

Tutorial ini, yang ditujukan untuk memulai pengembang dengan pengetahuan tentang HTML, JavaScript, dan CSS, akan membahas dasar-dasar React dan kesalahan paling umum yang mungkin dihadapi oleh seorang programmer yang menggunakan perpustakaan ini.

Mengapa pengembang web memilih Bereaksi?


Sebelum kita memulai bisnis, katakan beberapa kata tentang mengapa React dapat dianggap sebagai alternatif terbaik di antara alat untuk mengembangkan antarmuka web. Ada banyak kerangka kerja UI. Mengapa memilih Bereaksi? Untuk menjawab pertanyaan ini, mari kita bandingkan dua alat pengembangan antarmuka paling populer - Bereaksi dan Angular. Perlu dicatat bahwa kerangka kerja Vue.js, yang mulai populer, dapat dimasukkan dalam perbandingan ini, tetapi kami akan membatasi diri untuk React dan Angular.

â–Ť Pendekatan deklaratif untuk deskripsi antarmuka


Bereaksi pengembangan terdiri dalam menggambarkan apa yang perlu ditampilkan pada halaman (dan tidak dalam menyusun instruksi untuk browser tentang cara melakukan ini). Ini, antara lain, berarti pengurangan yang signifikan dalam jumlah kode boilerplate.

Angular, di sisi lain, memiliki alat baris perintah yang menghasilkan kode komponen boilerplate. Apakah ini tampak sedikit berbeda dari apa yang dapat Anda harapkan dari alat pengembangan antarmuka modern? Faktanya, kita berbicara tentang fakta bahwa ada begitu banyak kode templat di Angular sehingga untuk menghasilkannya, bahkan alat khusus telah dibuat.

Di Bereaksi, mulai berkembang, mereka hanya mulai menulis kode. Tidak ada kode komponen boilerplate yang perlu dibuat entah bagaimana. Tentu saja, beberapa persiapan diperlukan sebelum pengembangan, tetapi ketika datang ke komponen, mereka dapat digambarkan sebagai fungsi murni.

â–Ť Hapus sintaksis


Kode sudut menggunakan arahan seperti ng-model , ngIf dan ngFor . Kode ini terlihat agak rumit. React, di sisi lain, menggunakan sintaks JSX, yang dianggap sebagai HTML biasa, yaitu, untuk memulai pengembangan React, Anda tidak perlu mempelajari hal-hal baru yang fundamental. Begini tampilannya:

 const Greetings = ({ firstName }) => (  <div>Hi, {firstName}</div> ); 

â–Ť Kurva pembelajaran yang benar


Kurva pembelajaran merupakan faktor penting untuk dipertimbangkan ketika memilih kerangka kerja UI. Dalam hal ini, perlu dicatat bahwa ada lebih sedikit abstraksi dalam Bereaksi daripada di Angular. Jika Anda tahu JavaScript, maka Anda mungkin bisa belajar cara menulis Bereaksi aplikasi secara harfiah sehari. Tentu saja, untuk mempelajari cara melakukannya dengan benar, itu akan memakan waktu, tetapi Anda dapat bekerja dengan sangat, sangat cepat.

Jika Anda menganalisis Angular, ternyata jika Anda memutuskan untuk menguasai kerangka kerja ini, Anda harus mempelajari bahasa baru (Angular using TypeScript), serta mempelajari cara menggunakan alat baris perintah Angular dan terbiasa bekerja dengan arahan.

â–Ť Fitur mekanisme pengikatan data


Angular memiliki sistem pengikatan data dua arah. Ini, misalnya, dinyatakan dalam fakta bahwa perubahan dalam bentuk unsur mengarah ke pembaruan otomatis keadaan aplikasi. Ini menyulitkan debugging dan merupakan kerugian besar dari kerangka kerja ini. Dengan pendekatan ini, jika terjadi kesalahan, programmer tidak dapat mengetahui secara pasti apa yang menyebabkan aplikasi berubah status.

Bereaksi, di sisi lain, menggunakan pengikatan data satu arah. Ini adalah nilai tambah yang besar dari perpustakaan ini, karena dinyatakan dalam kenyataan bahwa programmer selalu tahu persis apa yang menyebabkan perubahan dalam keadaan aplikasi. Pendekatan ini untuk pengikatan data sangat menyederhanakan debugging aplikasi.

Approach Pendekatan fungsional untuk pembangunan


Saya percaya bahwa salah satu poin kuat React adalah kenyataan bahwa perpustakaan ini tidak memaksa pengembang untuk menggunakan kelas. Di Angular, semua komponen harus diimplementasikan sebagai kelas. Ini menyebabkan kompleksitas kode yang berlebihan, tanpa memberikan keuntungan apa pun.

Di Bereaksi, semua komponen antarmuka pengguna dapat dinyatakan sebagai set fungsi murni. Menggunakan fungsi murni untuk membentuk UI dapat dibandingkan dengan menghirup udara bersih.

Sekarang kami telah memeriksa alasan popularitas React, yang, sangat mungkin, akan membuat Anda condong ke perpustakaan khusus ini ketika memilih alat untuk mengembangkan antarmuka pengguna, mari beralih ke praktik.

Bereaksi Praktek Pengembangan Aplikasi


â–ŤNode.js


Node.js adalah platform server yang mendukung eksekusi kode JavaScript, yang kemampuannya berguna bagi kami untuk pengembangan Bereaksi. Jika Anda belum menginstal platform ini, sekarang saatnya untuk memperbaikinya .

â–ŤPersiapan proyek


Di sini kita akan menggunakan paket create-react-app dari Facebook untuk membuat inti dari aplikasi Bereaksi. Ini mungkin pendekatan yang paling populer untuk menyiapkan lingkungan kerja, yang memungkinkan Anda untuk memulai pengembangan. Berkat aplikasi create-react-app programmer dapat mengambil banyak alat yang diperlukan, yang menghilangkan kebutuhan untuk memilihnya sendiri.

Untuk menginstal create-react-app , gunakan perintah ini:

 npm i -g create-react-app 

Kemudian, untuk membuat templat aplikasi, jalankan perintah berikut:

 create-react-app react-intro 

Persiapan awal ini selesai. Untuk meluncurkan aplikasi, jalankan perintah berikut:

 cd react-intro npm start 

Di sini kita pergi ke folder proyek dan meluncurkan server pengembangan, yang memungkinkan Anda untuk membuka aplikasi Bereaksi baru dengan pergi ke browser di http: // localhost: 3000 / .

â–Ť Struktur proyek


Mari kita cari tahu bagaimana aplikasi Bereaksi bekerja. Untuk melakukan ini, buka proyek yang baru saja Anda buat menggunakan IDE Anda (saya sarankan Visual Studio Code ).

File index.html


Di folder proyek, buka file yang terletak di public/index.html . Inilah yang akan Anda lihat dengan melakukan ini.


File index.html

Di sini kami sangat tertarik pada baris <div id="root"> . Di sinilah aplikasi Bereaksi kami akan berlokasi. Semua elemen ini akan diganti dengan kode aplikasi, dan yang lainnya akan tetap tidak berubah.

File index.js


Sekarang buka file src/index.js . File ini adalah yang menyebarkan aplikasi Bereaksi. Dan, omong-omong, kode sumber aplikasi akan ditempatkan di direktori src .


File index.js

Berikut adalah baris kode yang bertanggung jawab untuk mengeluarkan apa yang kita sebut "Bereaksi aplikasi" ke halaman:

 ReactDOM.render(<App />, document.getElementById('root')); 

Baris ini memberi tahu React bahwa kita perlu mengambil komponen App (kami akan segera membicarakannya) dan menempatkannya di root div , yang ditentukan dalam file index.html yang baru saja kita periksa.

Sekarang kita akan berurusan dengan konstruk <App /> . Ini sangat mirip dengan kode HTML, tetapi ini adalah contoh kode JSX, yang merupakan sintaksis JavaScript khusus yang digunakan oleh React. Harap perhatikan bahwa konstruksi ini dimulai dengan huruf kapital A , yang persis <App /> , dan bukan <app /> . Ini karena konvensi penamaan entitas yang digunakan dalam React. Pendekatan ini memungkinkan sistem untuk membedakan antara tag HTML biasa dan komponen Bereaksi. Jika nama komponen tidak dikapitalisasi, Bereaksi tidak akan dapat menampilkannya di halaman.

Jika Anda berencana untuk menggunakan JSX dalam file .js tertentu, Anda perlu mengimpor Bereaksi di sana menggunakan perintah berikut:

 import React from 'react'; 

File App.js


Sekarang kita siap untuk melihat kode komponen pertama kita. Untuk melakukan ini, buka file src/App.js


File App.js

Untuk membuat komponen Bereaksi, Anda harus terlebih dahulu membuat kelas yang merupakan turunan dari React.Component . Ini adalah persis apa yang class App extends Component baris class App extends Component . Semua komponen Bereaksi harus mengandung implementasi metode render , di mana, seperti yang dapat Anda tebak dari namanya, komponen tersebut dibuat dan deskripsi representasi visualnya dihasilkan. Metode ini harus mengembalikan markup HTML untuk output ke halaman.

Perhatikan bahwa atribut className adalah setara dengan atribut class dalam HTML. Ini digunakan untuk menetapkan kelas CSS ke elemen untuk menata gaya mereka. Kelas kata kunci JavaScript dicadangkan dan tidak dapat digunakan sebagai nama atribut.

Mari kita ulangi apa yang baru saja kita ketahui tentang komponen:

  1. Nama mereka dimulai dengan huruf kapital ( A dalam App ).
  2. Mereka memperluas kelas React.Component .
  3. Mereka harus menerapkan metode render yang mengembalikan markup.

Sekarang mari kita bicara tentang apa yang harus dihindari ketika mengembangkan Bereaksi aplikasi.

OmmendRekomendasi No. 1: tidak perlu menggunakan kelas komponen di mana saja


Komponen dalam Bereaksi dapat dibuat menggunakan dua pendekatan. Yang pertama adalah menggunakan kelas komponen (Komponen Kelas), yang kedua adalah menggunakan komponen fungsional (Komponen Fungsional). Seperti yang mungkin Anda perhatikan, contoh di atas menggunakan kelas. Sayangnya, sebagian besar tutorial pemula Bereaksi menyarankan untuk menggunakannya.

Apa yang salah dengan menggambarkan komponen menggunakan mekanisme kelas? Faktanya adalah komponen seperti itu sulit untuk diuji dan mereka cenderung tumbuh berlebihan. Komponen-komponen ini tunduk pada masalah pemisahan tanggung jawab yang berkualitas rendah, pencampuran logika dan presentasi visual (dan ini mempersulit proses debug dan pengujian aplikasi). Secara umum, penggunaan kelas komponen mengarah pada fakta bahwa programmer, secara kiasan berbicara, "menembak dirinya sendiri di kaki." Oleh karena itu, terutama ketika datang ke programmer pemula, saya akan merekomendasikan bahwa mereka tidak menggunakan kelas komponen sama sekali.

Jadi, kami menemukan bahwa menggunakan kelas untuk menggambarkan komponen bukanlah ide yang baik. Alternatif apa yang kita miliki? Jawaban atas pertanyaan ini adalah komponen fungsional. Jika komponen yang dibuat menggunakan kelas tidak memiliki apa-apa selain metode render , maka itu adalah kandidat yang sangat baik untuk memprosesnya menjadi komponen fungsional. Berbekal gagasan ini, mari kita pikirkan tentang cara meningkatkan komponen App dibuat oleh alat create-react-app :

 function App() { return (   <div className="App">     ...   </div> ); } export default App; 

Lihat apa yang kami lakukan di sini? Yaitu, kami menghapus kelas dan mengganti metode render dengan konstruksi function App() {...} form function App() {...} . Jika kita menggunakan sintaks fungsi panah ES6 di sini, kode kita akan terlihat lebih baik:

 const App = () => ( <div className="App">   ... </div> ); export default App; 

Kami mengubah kelas menjadi fungsi yang mengembalikan markup yang perlu ditampilkan pada halaman.

Pertimbangkan ini. Fungsi yang mengembalikan markup tidak memiliki kode boilerplate. Ini markup hampir murni. Bukankah itu sempurna?

Kode komponen fungsional jauh lebih mudah dibaca, bekerja dengan mereka, Anda harus jauh lebih sedikit terganggu oleh desain standar.

Perlu dicatat di sini bahwa walaupun kita baru saja mengatakan bahwa komponen fungsional lebih disukai daripada kelas komponen, dalam artikel ini kita terutama akan menggunakan kelas, karena kode kelas komponen lebih jelas untuk pemula, ia bergantung pada abstraksi yang lebih sedikit, dengan Lebih mudah untuk menunjukkan konsep Bereaksi kunci. Tetapi ketika Anda cukup akrab dengan pengembangan aplikasi Bereaksi, sangat disarankan untuk mempertimbangkan, ketika mengembangkan proyek nyata, apa yang dikatakan di atas. Untuk lebih memahami komponen fungsional - lihat materi ini .

â–Ť Berkenalan dengan properti


Properti (alat peraga) adalah salah satu konsep utama React. Apa itu "properti"? Untuk memahami ini, ingat parameter yang dilewatkan ke fungsi. Intinya, properti adalah parameter yang diteruskan ke komponen. Pertimbangkan kode berikut:

 const Greetings = (props) => <div>Hey you! {props.firstName} {props.lastName}!</div>; const App = () => ( <div>   <Greetings firstName="John" lastName="Smith" /> </div> ); 

Di sini kami membuat komponen Greetings dan menggunakannya untuk menyambut seorang pria bernama John Smith dari komponen App . Semua kode ini akan menghasilkan markup HTML berikut:

 <div>  <div>Hey you! John Smith!</div> </div> 

Kurung kurawal dalam ekspresi seperti {props.name} digunakan untuk menyorot kode JavaScript. Komponen Greetings dilewatkan, dalam bentuk parameter, properti firstName dan lastName . Kami bekerja dengan mereka, mengacu pada properti dari objek props .

Perhatikan bahwa objek props tunggal props , bukan dua nilai yang mewakili properti firstName dan lastName .

Kode dapat disederhanakan dengan memanfaatkan kemampuan ES6 untuk merestrukturisasi objek:

 const Greetings = ({ firstName, lastName }) => <div>Hey you! {firstName} {lastName}!</div>; 

Seperti yang Anda lihat, di sini konstruksi (props) diganti oleh ({ firstName, lastName }) . Dengan penggantian ini, kami memberi tahu sistem bahwa kami hanya tertarik pada dua properti objek props . Dan ini, pada gilirannya, memungkinkan kita untuk secara langsung mengakses nilai firstName dan lastName tanpa secara eksplisit menentukan properti objek seperti props.firstName .

Bagaimana jika, untuk mengatasi masalah yang sama, alih-alih komponen fungsional, kita akan menggunakan komponen berbasis kelas? Dalam hal ini, kode komponen Greetings akan terlihat seperti ini:

 class Greetings extends React.Component { render() {   return (     <div>Hey you! {this.props.firstName} {this.props.lastName}!</div>   ); } } 

Saya tidak tahu sensasi apa yang ditimbulkan oleh kode ini terhadap Anda, tetapi bagi saya rasanya terlalu banyak dengan mekanisme bantu. Di sini, khususnya, untuk mengakses properti, Anda harus menggunakan konstruksi dari formulir this.props .

â–Ť prinsip tanggung jawab tunggal


Prinsip Tanggung Jawab Tunggal (SRP) adalah salah satu prinsip pemrograman yang paling penting untuk dipatuhi. Dia memberi tahu kita bahwa modul harus menyelesaikan hanya satu masalah dan harus melakukannya dengan kualitas. Jika Anda mengembangkan proyek tanpa mengikuti prinsip ini sendirian, kode untuk proyek semacam itu dapat berubah menjadi desain mimpi buruk yang tidak dapat didukung.

Bagaimana prinsip tanggung jawab tunggal dilanggar? Paling sering ini terjadi ketika mekanisme yang tidak terkait satu sama lain ditempatkan dalam file yang sama. Dalam materi ini kita akan sering merujuk pada prinsip ini.

Pemula biasanya menempatkan banyak komponen dalam satu file. Misalnya, kami memiliki kode untuk komponen Greetings dan App dalam file yang sama. Dalam praktiknya, ini tidak boleh dilakukan, karena ini melanggar SRP.

Bahkan komponen yang sangat kecil (seperti komponen Greetings kami) perlu ditempatkan dalam file terpisah.

Tempatkan kode komponen Greetings dalam file terpisah:

 import React from "react"; const Greetings = ({ firstName, lastName }) => (   <div>       Hey you! {firstName} {lastName}!   </div> ); export default Greetings; 

Kemudian gunakan komponen ini di komponen App :

 import Greetings from "./Greetings"; const App = () => ( ... ); 

Perhatikan bahwa nama file harus cocok dengan nama komponen. Yaitu, kode komponen App harus ditempatkan di file App.js , kode komponen Greetings dalam file Greetings , dan sebagainya.

â–Ť Keakraban dengan keadaan aplikasi


Negara adalah konsep sentral lain dalam React. Di sinilah data aplikasi disimpan - yaitu, apa yang bisa berubah. Perlu menyimpan sesuatu yang dimasukkan di bidang formulir? Gunakan status. Perlu menyimpan poin yang dicetak oleh pemain di game browser? Untuk melakukan ini, Anda harus menggunakan status aplikasi.

Mari kita buat formulir sederhana yang dengannya pengguna dapat memasukkan namanya. Harap dicatat bahwa di sini saya sengaja menggunakan kelas untuk menggambarkan komponen, karena ini membuatnya lebih mudah untuk menunjukkan konsep yang dimaksud. Anda dapat membaca tentang cara mengubah komponen yang dibuat menggunakan kelas menjadi komponen fungsional di sini .

 import React from "react"; class SimpleForm extends React.Component { render() {   return (     <div>       <input type="text" name="firstName" />       <Greetings firstName="John" />     </div>   ); } } const App = () => ( <div>   <SimpleForm /> </div> ); 

Pengguna dapat memasukkan sesuatu di bidang formulir, dan itu bagus. Namun, jika Anda hati-hati membaca kode ini, Anda mungkin memperhatikan bahwa John selalu digunakan sebagai nama pengguna dalam output di halaman pembuka. Bagaimana jika tidak semua pengguna kami dipanggil seperti itu? Jika demikian, maka kita menempatkan diri kita pada posisi yang tidak nyaman.

Bagaimana cara menggunakan nilai yang dimasukkan di bidang? Bereaksi tidak bergantung pada elemen DOM secara langsung. Penangan acara dan status aplikasi akan membantu kami memecahkan masalah ini.

 class SimpleForm extends React.Component { state = {   firstName: "", }; onFirstNameChange = event =>   this.setState({     firstName: event.target.value   }); render() {   return (     <div>       <input type="text" name="firstName" onChange={this.onFirstNameChange} />       <Greetings firstName={this.state.firstName} />     </div>   ); } } 

Anda bisa membayangkan keadaan sebagai objek JavaScript sederhana, yang, dalam bentuk properti, disimpan di kelas komponen SimpleForm . Di objek ini, kami menambahkan properti firstName .

Di sini kami melengkapi bidang Nama depan dengan pengendali acara. Itu dimulai setiap kali pengguna memasukkan setidaknya satu karakter dalam bidang. Di kelas, properti onChange bertanggung jawab untuk memproses onFirstNameChange onChange , di mana perintah berikut dijalankan:

 this.setState(...) 

Di sinilah keadaan komponen diperbarui. Status komponen tidak diperbarui secara langsung. Ini hanya dilakukan dengan setState metode setState . Untuk menulis nilai baru ke properti firstName , kami cukup memberikan metode ini objek yang berisi apa yang perlu ditulis ke negara:

 { firstName: event.target.value } 

Dalam hal ini, event.target.value adalah apa yang dimasukkan pengguna di bidang formulir, yaitu namanya.

Perhatikan bahwa kami tidak mendeklarasikan onFirstNameChange sebagai metode. Sangat penting bahwa hal-hal tersebut dideklarasikan dalam bentuk properti kelas yang berisi fungsi panah, dan bukan dalam bentuk metode. Jika Anda mendeklarasikan fungsi serupa sebagai metode, maka this akan terikat pada elemen formulir yang memanggil metode ini, dan bukan ke kelas, seperti yang mungkin kita harapkan. Hal kecil ini sering membingungkan bagi pemula. Ini adalah salah satu alasan untuk merekomendasikan penggunaan komponen fungsional daripada kelas komponen.

â–ŤPeriksa data yang dimasukkan pada formulir


Kami menerapkan sistem sederhana untuk memeriksa data yang dimasukkan ke dalam formulir menggunakan ekspresi reguler. Mari kita putuskan bahwa nama harus terdiri dari paling tidak tiga karakter dan hanya boleh mengandung huruf.

Tambahkan event handler onBlur ke komponen, yang dipanggil ketika pengguna meninggalkan bidang input. Tambahkan properti lain ke status aplikasi - firstNameError . Jika terjadi kesalahan saat memasukkan nama, kami akan menampilkan pesan tentang ini di bawah bidang.

Mari kita menganalisis kode ini.

 class SimpleForm extends React.Component { state = {   firstName: "",   firstNameError: "", }; validateName = name => {   const regex = /[A-Za-z]{3,}/;   return !regex.test(name)     ? "The name must contain at least three letters. Numbers and special characters are not allowed."     : ""; }; onFirstNameBlur = () => {   const { firstName } = this.state;   const firstNameError = this.validateName( firstName );   return this.setState({ firstNameError }); }; onFirstNameChange = event =>   this.setState({     firstName: event.target.value   }); render() {   const { firstNameError, firstName } = this.state;   return (     <div>       <div>         <label>           First name:           <input             type="text"             name="firstName"             onChange={this.onFirstNameChange}             onBlur={this.onFirstNameBlur}           />           {firstNameError && <div>{firstNameError}</div>}         </label>       </div>       <Greetings         firstName={firstName}       />     </div>   ); } } 

Status aplikasi


Mengembangkan sistem verifikasi input, kami, sebagai permulaan, menambahkan properti baru ke status: firstNameError :

 state = {  ...  firstNameError: "", }; 

Fungsi validasi data


Validasi data dilakukan dalam fungsi panah validateName . Ini memvalidasi nama yang dimasukkan dengan ekspresi reguler:

 validateName = name => { const regex = /[A-Za-z]{3,}/; return !regex.test(name)    ? "The name must contain at least three letters..."    : ""; } 

Jika pemeriksaan gagal, kami mengembalikan pesan kesalahan dari fungsi. Jika nama lulus tes, kami mengembalikan string kosong yang menunjukkan bahwa tidak ada kesalahan ditemukan selama pemeriksaan nama. Di sini, demi singkatnya, kami menggunakan JavaScript operator ternary.

Handler event OnBlur


onBlur event onBlur , yang dipanggil saat pengguna meninggalkan kolom input:

 onFirstNameBlur = () => { const { firstName } = this.state; const firstNameError = this.validateName( firstName ); return this.setState({ firstNameError }); }; 

Di sini kita mengekstrak properti firstName dari negara, mengambil keuntungan dari kemampuan ES6 untuk merusak objek. Baris pertama dari kode ini setara dengan ini:

 const firstName = this.state.firstName; 

Kemudian kita memanggil fungsi verifikasi data yang dijelaskan di atas, meneruskannya firstName , dan menulis ke properti negara firstNameError apa fungsi ini kembali. Jika pemeriksaan gagal, pesan kesalahan akan dikirim ke properti ini. Jika berhasil, baris kosong akan ditulis di sana.

Metode render


Pertimbangkan metode render() komponen render() :

 render() {  const { firstNameError, firstName} = this.state;  ... } 

.

 <input ... onBlur={this.onFirstNameBlur} /> 

onFirstNameBlur onBlur .

 {firstNameError && <div>{firstNameError}</div>} 

JavaScript. div , , , firstNameError true .

â–Ť


, , , . , :

 render() { const { firstNameError, firstName } = this.state; return (   <div       style={{         margin: 50,         padding: 10,         width: 300,         border: "1px solid black",         backgroundColor: "black",         color: "white"       }}     >     <div style={{marginBottom: 10}}>       <label>         First name:         <input           style={{backgroundColor: '#EFEFFF', marginLeft: 10}}           type="text"           name="firstName"           onChange={this.onFirstNameChange}           onBlur={this.onFirstNameBlur}         />         {firstNameError && <div style={{color: 'red', margin: 5}}>{firstNameError}</div>}       </label>     </div>     <Greetings       firstName={firstName}     />   </div> ); } 

React style .

, , , , , . , .




â–Ť â„–2:


, , React-. , , — render , , . ? , . , , .

? , . style , . . , style.js :

 // style.js: const style = {   form: {       margin: 50,       padding: 10,       width: 300,       border: "1px solid black",       backgroundColor: "black",       color: "white"   },   inputGroup: {       marginBottom: 10   },   input: {       backgroundColor: "#EFEFFF",       marginLeft: 10   },   error: {       color: "red",       margin: 5   } }; export default style; 

, , SimpleComponent :

 import style from './style'; class SimpleForm extends React.Component {   ...       render() {       const { firstNameError, firstName } = this.state;         return (         <div style={style.form}>           <div style={style.inputGroup}>             <label>               First name:               <input                 style={style.input}                 type="text"                 name="firstName"                 onChange={this.onFirstNameChange}                 onBlur={this.onFirstNameBlur}               />               {firstNameError && (                 <div style={style.error}>{firstNameError}</div>               )}             </label>           </div>             <Greetings firstName={firstName} />         </div>       );     } } export default SimpleForm; 

, . .

â–Ť


, :

 class SimpleForm extends React.Component { state = {   ...   lastName: "",   lastNameError: "" }; validateName = ...; onFirstNameBlur = ...; onFirstNameChange = ...; onLastNameBlur = () => {   const { lastName } = this.state;   const lastNameError = this.validateName(lastName);   return this.setState({ lastNameError }); }; onLastNameChange = event =>   this.setState({     lastName: event.target.value   }); render() {   const { firstNameError, firstName, lastName, lastNameError } = this.state;   return (     <div style={style.form}>       <div style={style.inputGroup}>         <label>           First name:           <input             style={style.input}             type="text"             name="firstName"             onChange={this.onFirstNameChange}             onBlur={this.onFirstNameBlur}           />           {firstNameError && <div style={style.error}>{firstNameError}</div>}         </label>       </div>       <div style={style.inputGroup}>         <label>           Last name:           <input             style={style.input}             type="text"             name="lastName"             onChange={this.onLastNameChange}             onBlur={this.onLastNameBlur}           />           {lastNameError && <div style={style.error}>{lastNameError}</div>}         </label>       </div>       <Greetings firstName={firstName} lastName={lastName} />     </div>   ); } } export default SimpleForm; 

— , firstName .

«»? — , .

â–Ť â„–3:


, , , , , . , , render . .

, , , . TextField , .

 import React from 'react' import style from "./style"; const TextField = ({name, onChange, onBlur, error, label}) => ( <div style={style.inputGroup}>   <label>     {label}     <input       style={style.input}       type="text"       name={name}       onChange={onChange}       onBlur={onBlur}     />     {error && <div style={style.error}>{error}</div>}   </label> </div> ); export default TextField; 

, , render . , , .

SimpleForm :

 ... import TextField from './TextField'; class SimpleForm extends React.Component { ... render() {   const { firstNameError, firstName, lastName, lastNameError } = this.state;   return (     <div style={style.form}>       <TextField name="firstName"                  label="First name:"                  onChange={this.onFirstNameChange}                  onBlur={this.onFirstNameBlur}                  error={firstNameError} />       <TextField name="lastName"                  label="Last name:"                  onChange={this.onLastNameChange}                  onBlur={this.onLastNameBlur}                  error={lastNameError} />       <Greetings firstName={firstName} lastName={lastName} />     </div>   ); } } 

, . , TextField . FirstNameField :

 import React from 'react'; import TextField from './TextField'; const FirstNameField = ({...rest}) => ( <TextField name="firstName"             label="First name:"             {...rest} /> ); export default FirstNameField; 

, . ({...rest}) ( rest, ). , , , rest . , , TextField , « », spread (, {...rest} , ). rest , , TextField .

, : , FirstNameField TextField .

LastNameField :
:

 ... import FirstNameField from './FirstNameField'; import LastNameField from './LastNameField'; class SimpleForm extends React.Component { ... render() {   const { firstNameError, firstName, lastName, lastNameError } = this.state;   return (     <div style={style.form}>       <FirstNameField onChange={this.onFirstNameChange}                       onBlur={this.onFirstNameBlur}                       error={firstNameError} />       <LastNameField onChange={this.onLastNameChange}                       onBlur={this.onLastNameBlur}                       error={lastNameError} />       <Greetings firstName={firstName} lastName={lastName} />     </div>   ); } } 

.

â–Ť


, , , :

  • , , , .
  • . , , , , 1000 ( ).
  • , . , , .
  • , , , . . , , . , , , .
  • , , , , .
  • this , .

Ringkasan


, React- . , , , , . , , , React, , , , UI-.

→ , ,

Pembaca yang budiman! , , React-, .

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


All Articles