Tantangan Penanganan Form pada React
Mengelola input pengguna di React sering kali membutuhkan banyak boilerplate state (useState untuk setiap field), pesan error manual, dan risiko tipe data yang tidak sinkron antara validasi frontend dan API backend.
Solusi: Combination Zod & React Hook Form
- Zod: Pustaka deklarasi skema tipe-safe TypeScript first.
- React Hook Form: Pustaka pengelola state formulir yang sangat hemat re-render.
1. Mendefinisikan Skema Zod
import { z } from 'zod';
export const contactFormSchema = z.object({
name: z.string().min(2, "Nama minimal 2 karakter"),
email: z.string().email("Format email tidak valid"),
message: z.string().min(10, "Pesan minimal 10 karakter"),
});
// Inferensi Tipe TypeScript Otomatis!
export type ContactFormValues = z.infer<typeof contactFormSchema>;
2. Mengintegrasikan dengan React Hook Form
Gunakan @hookform/resolvers/zod untuk menyambungkan skema ke komponen formulir:
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { contactFormSchema, type ContactFormValues } from './schema';
export function ContactForm() {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<ContactFormValues>({
resolver: zodResolver(contactFormSchema),
});
const onSubmit = async (data: ContactFormValues) => {
await fetch('/api/contact', {
method: 'POST',
body: JSON.stringify(data),
});
};
return (
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<div>
<input {...register('name')} placeholder="Nama Lengkap" className="input" />
{errors.name && <p className="text-red-500 text-xs mt-1">{errors.name.message}</p>}
</div>
<div>
<input {...register('email')} type="email" placeholder="Email" className="input" />
{errors.email && <p className="text-red-500 text-xs mt-1">{errors.email.message}</p>}
</div>
<button type="submit" disabled={isSubmitting} className="btn">
{isSubmitting ? 'Mengirim...' : 'Kirim Pesan'}
</button>
</form>
);
}
Kesimpulan
Kombinasi Zod dan React Hook Form menghapus re-render yang tidak perlu, menjamin validasi skema yang konsisten, dan memfasilitasi inferred types secara instan dari skema ke handler API!