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.

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:
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.

<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) { 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
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
.
import { LayoutContext } from './form' 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
import { LayoutContext } from './form' function Field(props) { 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; } .form-field.label-on-top label { text-align: left; margin-bottom: 25px; }
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:
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.
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).