Membuat Pustaka Validasi React Anda Sendiri: Pengalaman Pengembang (Bagian 3)

Diterbitkan: 2022-03-10
Ringkasan cepat Jadi kita telah melihat bagaimana kita dapat mengimplementasikan bagian dasar dari library validasi kita, dan bagaimana menambahkan semua fitur bagus yang kita butuhkan. Bagian terakhir dari seri ini akan fokus pada peningkatan pengalaman pengguna bagi orang-orang yang akan menggunakan perpustakaan validasi kami: para pengembang.

Jika Anda telah mengikuti rangkaian artikel kecil ini, Anda sekarang telah belajar bagaimana menyusun perpustakaan validasi Anda sendiri. Ini dapat menangani hampir semua tantangan yang dapat Anda lakukan, dan bahkan membantu dengan masalah aksesibilitas! Satu-satunya kekurangannya adalah itu menyebalkan untuk dikerjakan.

Ya, itu benar. Pengalaman pengguna dari sudut pandang pengembang sangat kurang. Kami tidak mendapatkan peringatan yang berguna saat kami salah mengeja kata, menyalahgunakan API, atau, apa pun, sungguh!

Artikel ini akan memandu Anda tentang bagaimana Anda dapat meningkatkan pengalaman pengembang perpustakaan validasi Anda — atau perpustakaan apa pun untuk itu.

  • Bagian 1: Dasar-dasar
  • Bagian 2: Fitur
  • Bagian 3: Pengalaman

Memulai

Sejak bagian terakhir artikel ini, kami telah mengeluarkan semua kode perpustakaan ke dalam filenya sendiri. Lihatlah demo CodeSandbox untuk melihat apa yang kami mulai.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

Fungsi Kenyamanan

Kami ingin perpustakaan kami sesederhana mungkin digunakan untuk kasus yang paling umum. Cara untuk bergerak ke arah tujuan itu adalah dengan menambahkan fungsi utilitas yang nyaman untuk fungsi tertentu.

Salah satu fitur tersebut adalah untuk memeriksa apakah formulir kita valid — yaitu, jika semua pesan kesalahan adalah null . Ini adalah sesuatu yang biasanya Anda periksa di handler onSubmit Anda, tetapi bisa juga berguna dalam metode render Anda. Mari kita terapkan!

 const isFormValid = useMemo( () => Object.values(errors).every(error => error === null), [errors] );

Kami akan memberikan tanda ini di penangan formulir onSubmit kami, serta dalam metode render kami.

  • Lihat demo CodeSandbox

Ada banyak lagi yang bisa ditulis, tapi saya akan membiarkan itu menjadi latihan bagi pembaca.

Peringatan Pengembangan Dan Invarian

Salah satu fitur terbaik React adalah banyaknya peringatan konsol yang membantu saat pengembangan. Kami juga harus memberikan kualitas yang sama kepada pengguna kami.

Untuk memulai, kita akan membuat dua fungsi — warning untuk mencatat peringatan ke konsol, dan invariant untuk melempar kesalahan — keduanya jika kondisi yang diberikan tidak terpenuhi.

 function warning(condition, message) { if (process.env.NODE_ENV === 'production' || condition) { return; } console.warn('useValidation: ' + message); } function invariant(condition, message) { if (process.env.NODE_ENV === 'production' || condition) { return; } throw new Error('useValidation: ' + message); }

Anda ingin menggunakan invariant jika kesalahan akan membuat perpustakaan Anda mogok (atau membuatnya tidak berguna), dan warning untuk praktik buruk atau saran lainnya.

Kapan Harus Diperingatkan?

Memutuskan kapan harus memperingatkan cukup penting. Terlalu banyak, dan kau hanya mengganggu. Terlalu sedikit, dan Anda membiarkan bug kritis dikirim ke produksi. Oleh karena itu, kita harus cerdas dengan peringatan kita.

Karena perpustakaan kami menerima objek konfigurasi yang cukup besar, masuk akal untuk memvalidasi ini entah bagaimana — setidaknya saat berkembang. Kita bisa menyelesaikannya dengan menggunakan sistem tipe seperti TypeScript atau Flow, tapi itu tidak termasuk semua pengguna JavaScript biasa.

Sebagai gantinya, mari buat pemeriksa skema runtime, di mana kami memvalidasi bahwa konfigurasi berisi bidang yang benar, dan mencetak peringatan yang relevan.

 function validateConfigSchema(config) { if (process.env.NODE_ENV === 'production') { return; } if (typeof config === 'function') { config = config({}); } invariant( typeof config === 'object', `useValidation should be called with an object or a function returning an object. You passed a ${typeof config}.`, ); invariant( typeof config.fields === 'object', 'useValidation requires a `field` prop with an object containing the fields and their validators. Please refer to the documentation on usage: https://link.to/docs' ); invariant( Object.values(config.fields).every(field => typeof field === 'object'), 'useValidation requires that the `field` object only contains objects. It looks like yours isn\'t. Please refer to the documentation on usage: https://link.to/docs' ); warning( ['always', 'blur', 'submit', undefined].includes(config.showError), 'useValidation received an unsupported value in the `showError` prop. Valid values are "always", "blur" or "submit".' ) // And so on }

Kami mungkin bisa terus melakukan ini untuk sementara waktu jika kami ingin menghabiskan waktu. Dan Anda harus! Ini adalah cara yang bagus untuk meningkatkan pengalaman pengembang aplikasi Anda.

Namun, Anda tidak harus menulis ini dengan tangan. Ada port browser dari perpustakaan joi skema objek populer yang dapat membantu membuat pemeriksaan validasi runtime yang sangat bagus. Juga, seperti yang disebutkan sebelumnya, sistem tipe akan membantu menangkap kesalahan konfigurasi pada waktu kompilasi untuk pengguna yang menggunakan sistem tipe itu.

Memungkinkan Untuk Fleksibilitas

Pengalaman pengembang yang baik sebagian besar tidak menghalangi pengembang. Mari kita lihat beberapa cara untuk meningkatkan pengalaman itu.

Tulis Alat Peraga yang Bertentangan

Pertama, prop getter kami menerapkan beberapa prop ke input dan formulir kami yang dapat secara tidak sengaja ditimpa oleh konsumen kami. Sebagai gantinya, mari tambahkan objek prop override ke prop getter kita, yang akan menyusun props yang bertentangan bersama-sama.

Inilah cara kami mengimplementasikan ini di getFieldProps kami:

 getFieldProps: (fieldName, overrides = {}) => ({ onChange: e => { const { value } = e.target; if (!config.fields[fieldName]) { return; } dispatch({ type: 'change', payload: { [fieldName]: value }, }); if (overrides.onChange) { overrides.onChange(e); } }, onBlur: e => { dispatch({ type: 'blur', payload: fieldName }); if (overrides.onBlur) { overrides.onBlur(e) } }, name: overrides.name || fieldName, value: state.values[fieldName] || '', }),

Pendekatan serupa dapat diikuti di getFormProps .

Bantu Hindari Pengeboran Prop

Beberapa bentuk mungkin berukuran besar dan terbagi menjadi beberapa komponen. Alih-alih membuat alat peraga bor konsumen kita turun dari pohon, kita harus memberikan konteks. Dengan cara ini, mereka dapat mengakses semua barang yang kami kembalikan dari kait khusus kami di mana saja di pohon di bawah ini.

Pertama, mari buat ValidationContext dengan metode createContext React:

 export const ValidationContext = React.createContext({});

Selanjutnya, mari buat komponen ValidationProvider , yang menyediakan semua nilai dari kait useValidation dalam konteks sebagai gantinya:

 export const ValidationProvider = props => { const context = useValidation(props.config); return ( {props.children} ); }; export const ValidationProvider = props => { const context = useValidation(props.config); return ( {props.children} ); }; export const ValidationProvider = props => { const context = useValidation(props.config); return ( {props.children} ); };

Sekarang, daripada memanggil useValidation secara langsung, kita akan membungkus formulir kita dalam komponen ValidationProvider , dan mendapatkan akses ke props validasi ( getFormProps , errors , dll) dengan menggunakan kait useContext . Anda akan menggunakannya seperti ini:

 Import React, { useContext } from 'react'; import { ValidationContext } from './useValidation'; function UsernameForm(props) { const { getFieldProps, errors } = useContext(ValidationContext); return ( <> <input {...getFieldProps('username')} /> {errors.username && {errors.username}></span>} </> ); }

Dengan cara ini, Anda mendapatkan yang terbaik dari kedua dunia! Anda mendapatkan pengait sederhana untuk skenario sederhana itu, dan Anda mendapatkan fleksibilitas yang Anda butuhkan untuk bagian kompleks itu.

Dokumentasi Adalah Kunci

Setiap kali saya menggunakan perpustakaan, saya tidak menulis sendiri, saya suka dokumentasi yang bagus. Tapi apa yang harus Anda fokuskan, dan di mana Anda harus mendokumentasikannya?

Langkah pertama adalah menyusun README yang mudah dipahami, dengan contoh penggunaan paling dasar yang tersedia. Andrew Healey menulis artikel yang luar biasa tentang cara menulis README yang baik, yang sangat saya rekomendasikan untuk Anda baca.

Ketika Anda telah membuat README yang bagus untuk membuat orang pergi, situs web dokumentasi mungkin merupakan ide yang bagus. Di sini, Anda dapat meletakkan dokumentasi API yang lebih mendalam, resep untuk kasus penggunaan umum, dan FAQ yang bagus.

Ada alat hebat di luar sana untuk membuat situs web dokumentasi. Favorit saya adalah docusaurus dari Facebook (bual sederhana: kami menggunakannya saat membuat situs web create-react-app ), tetapi ada beberapa alternatif bagus di luar sana.

Kami tidak akan membahas cara menulis dokumentasi yang baik di artikel ini. Ada beberapa artikel bagus di luar sana — bahkan komunitas bernama “Write the Docs”. Mereka telah menulis panduan hebat tentang bagaimana Anda bisa mulai menulis dokumentasi yang bagus.

Ringkasan

Melalui seri artikel ini, kami telah membuat pustaka validasi yang cukup baik. Ini memiliki API yang cukup sederhana, fleksibilitas ketika Anda membutuhkannya, pengalaman pengembang yang baik, dan banyak fitur yang cukup lembap.

Kami telah melalui bagaimana kami mengimplementasikan berbagai hal selangkah demi selangkah, dan saya harap Anda mendapatkan pemahaman yang lebih dalam tentang bagaimana Anda dapat membuat perpustakaan Anda sendiri, dan bagaimana Anda menjadikannya sesuatu yang akan disukai orang untuk digunakan.

Tolong beri tahu saya di komentar apa yang Anda pikirkan, dan jika ada beberapa bagian yang Anda terjebak atau sulit dipahami. Saya akan mencoba yang terbaik untuk memperbarui artikel saat umpan balik masuk.

Untuk mengakhiri artikel ini — inilah versi finalnya:

  • Lihat demo CodeSandbox

Terima kasih sudah membaca!