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