Kami menulis API untuk komponen Bereaksi, bagian 6: kami membuat komunikasi antar komponen

Menulis API untuk komponen Bereaksi, bagian 1: jangan membuat alat peraga yang bertentangan

Menulis API untuk Komponen Bereaksi, Bagian 2: Beri Nama untuk Perilaku, Bukan Interaksi

Menulis API untuk komponen Bereaksi, bagian 3: urutan alat peraga penting

Menulis API untuk Komponen Bereaksi, Bagian 4: Waspadai Apropacalypse!

Menulis API untuk Komponen Bereaksi, Bagian 5: Cukup Gunakan Komposisi

Kami menulis API untuk komponen Bereaksi, bagian 6: kami membuat komunikasi antar komponen

Mari kita bicara tentang formulir.


Kemungkinan besar Anda membaca banyak artikel tentang manajemen state dalam bentuk, tetapi ini bukan salah satu dari artikel tersebut. Sebagai gantinya, saya ingin berbicara tentang cara kerja formulir dan API mereka.


label-di-kiri


Ada banyak hal yang terjadi di sini, lihatlah API


 <Form layout="label-on-left"> <Form.Field label="Name"> <TextInput type="text" placeholder="Enter your name" /> </Form.Field> <Form.Field label="Email"> <TextInput type="email" placeholder="email@domain.com" /> </Form.Field> </Form> 

Mari kita lihat masing-masing komponen dan menganalisisnya:


Formulir


Semuanya dimulai dengan komponen Form , yang merupakan elemen bentuk dasar dengan kelas terlampir. Ini akan membuat semua yang Anda masukkan ke dalamnya.


 function Form(props) { return <form className="form">{props.children}</form> } render(<Form layout="label-on-left">...</Form>) 

Ini juga menerima layout prop, yang berguna ketika Anda memiliki sedikit ruang.


label di telepon atas


 <Form layout="label-on-top">...</Form> 

Ini mengubah cara label disejajarkan (dari kanan ke kiri) dan bagaimana margin bekerja.


Formulir tidak mengontrol lebar dan margin konten internalnya. Ini sudah menjadi perhatian untuk bidang input di dalam formulir ini.


Jadi komponen Form harus melaporkan informasi layout bawah ini.


Cara termudah adalah dengan melewati layout menggunakan alat peraga, tetapi konten formulir bersifat dinamis (ditentukan oleh pengembang yang menggunakan formulir ini), kami tidak tahu persis apa bentuknya.


Di sinilah API konteks membantu kami.


 /*    */ const LayoutContext = React.createContext() function Form(props) { /*     `Provider`       */ return ( <form className="form"> <LayoutContext.Provider value={{ layout: props.layout }} > {props.children} </LayoutContext.Provider> </form> ) } export default Form export { LayoutContext } 

Sekarang bidang formulir dapat menggunakan konteks ini dan mendapatkan nilai layout


Bidang formulir


Komponen FormField (bidang input formulir) menambahkan label untuk semua yang Anda masukkan ke dalamnya (misalnya, input teks).


 function Field(props) { return ( <div className="form-field"> <label {...props}>{props.label}</label> {props.children} </div> ) } 

Selain itu, ia menambahkan kelas untuk layout - yang berasal dari konteks yang kami buat di komponen Form .


 /*   layout */ import { LayoutContext } from './form' /*           -     API (Render Prop API)         */ function Field(props) { return ( <LayoutContext.Consumer> {context => ( <div className={`form-field ${context.layout}`}> <label {...props}>{props.label}</label> {props.children} </div> )} </LayoutContext.Consumer> ) } 

Bereaksi 16.8+ useContext hook membuat sintaks lebih mudah


 /*   layout */ import { LayoutContext } from './form' function Field(props) { /*    useContext          */ const context = useContext(LayoutContext) return ( <div className={`form-field ${context.layout}`}> <label {...props}>{props.label}</label> {props.children} </div> ) } 

Jika Anda tertarik, berikut adalah kode css:


 .form-field.label-on-left { max-width: 625px; display: flex; align-items: center; /*    */ } .form-field.label-on-left label { text-align: right; width: 175px; margin-right: 25px; } .form-field.label-on-top { width: 100%; display: block; /*  flex*/ } .form-field.label-on-top label { text-align: left; /*  right */ margin-bottom: 25px; /*  margin-right */ } 

Form.Field?


Detail terakhir yang ingin saya bicarakan adalah sintaksis bertitik aneh ini untuk komponen.


Karena Field (bidang input) selalu digunakan dengan formulir, masuk akal untuk mengelompokkannya bersama.


Salah satu cara untuk melakukan ini adalah dengan mengekspornya dari file yang sama:


 /* form.js */ import Field from './field' function Form(props) { /* ... */ } export default Form export { Field } 

Dan sekarang pengguna dapat mengimpornya bersama-sama:


 import Form, { Field } from 'components/form' render( <Form> <Field>...</Field> </Form> ) 

Kami dapat membuat sedikit peningkatan dengan menempelkan Field ke komponen formulir.


 /* form.js */ import Field from './field' function Form(props) { /* ... */ } Form.Field = Field export default Form 

Kode ini berfungsi karena Bereaksi komponen adalah objek javascript, dan Anda dapat menambahkan kunci tambahan ke objek-objek ini.


Untuk pengguna, ini berarti bahwa ketika ia mengimpor Form , ia menerima Field secara otomatis.


 import Form from 'components/form' render( <Form> <Form.Field>...</Form.Field> </Form> ) 

Saya sangat suka API ini, itu membuat koneksi antara Form dan Form.Field jelas.


Catatan: Anda harus memindahkan konteks ke file lain untuk menghindari ketergantungan melingkar.


Kombinasi sintaks dengan titik-titik dan konteks membuat komponen Form kami pintar, sambil mempertahankan operabilitasnya untuk komposisi (komposit).

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


All Articles