Validasi form adalah salah satu aspek terpenting dalam pengembangan aplikasi web. Proses ini memastikan bahwa data yang dimasukkan oleh pengguna sesuai dengan format dan kriteria yang kita tentukan sebelum dikirim ke server. React Hook Form dan Zod adalah dua library yang sangat populer untuk menangani validasi form di React dengan cara yang efisien dan deklaratif.
Dalam artikel ini, kita akan membahas cara mengintegrasikan React Hook Form dengan Zod untuk membuat sistem validasi form yang kuat, mudah dikelola, dan minim boilerplate.
Mengapa React Hook Form + Zod?
Kombinasi keduanya menawarkan beberapa keuntungan utama:
Performa Tinggi: React Hook Form mengoptimalkan re-render dengan mengisolasi state form, sehingga aplikasi Anda tetap cepat dan responsif.
Kode yang Lebih Bersih: Dengan Zod, Anda mendefinisikan skema validasi sebagai satu sumber kebenaran (single source of truth). Ini menghilangkan kebutuhan untuk menulis logika validasi manual di dalam komponen Anda.
Keamanan Tipe (Type Safety): Zod secara otomatis menginferensi tipe TypeScript dari skema Anda, memastikan konsistensi tipe dari validasi hingga penggunaan data.
Kemudahan Penggunaan: API dari kedua library ini sangat intuitif dan mudah dipelajari.
Langkah-langkah Implementasi
Mari kita mulai membuat form registrasi sederhana dengan validasi untuk nama, email, dan password.
1. Instalasi Library
Pertama, pastikan Anda sudah memiliki proyek React. Kemudian, install library yang dibutuhkan melalui npm atau yarn.
Bash
npm install react-hook-form zod @hookform/resolvers
react-hook-form
: Library utama untuk manajemen form.
zod
: Untuk membuat skema validasi.
@hookform/resolvers
: Library penghubung antara React Hook Form dan Zod.
2. Membuat Skema Validasi dengan Zod
Buat sebuah file (misalnya validationSchema.js
) untuk mendefinisikan aturan validasi menggunakan Zod. Zod memungkinkan kita mendefinisikan objek skema dengan aturan yang sangat deskriptif.
JavaScript
import { z } from 'zod';
export const registrationSchema = z.object({
fullName: z.string().min(3, { message: "Nama lengkap minimal 3 karakter" }),
email: z.string().email({ message: "Format email tidak valid" }),
password: z.string().min(8, { message: "Password minimal 8 karakter" }),
confirmPassword: z.string(),
}).refine((data) => data.password === data.confirmPassword, {
message: "Konfirmasi password tidak cocok",
path: ["confirmPassword"], // Menentukan field mana yang akan menampilkan error
});
Dalam skema di atas:
fullName
harus berupa string dengan minimal 3 karakter.
email
harus berupa string dengan format email yang valid.
password
harus berupa string dengan minimal 8 karakter.
.refine()
digunakan untuk validasi kustom yang bergantung pada field lain, dalam kasus ini memastikan password
dan confirmPassword
sama.
3. Mengintegrasikan Skema ke dalam Form
Sekarang, kita akan menggunakan hook useForm
dari React Hook Form dan zodResolver
untuk menghubungkan skema Zod kita ke dalam komponen form.
Buat komponen form Anda (misalnya RegistrationForm.jsx
).
JavaScript
import React from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { registrationSchema } from './validationSchema';
const RegistrationForm = () => {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(registrationSchema),
});
const onSubmit = (data) => {
console.log(data);
alert('Registrasi berhasil! Cek konsol untuk melihat data.');
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="fullName">Nama Lengkap</label>
<input id="fullName" {...register('fullName')} />
{errors.fullName && <p style={{ color: 'red' }}>{errors.fullName.message}</p>}
</div>
<div>
<label htmlFor="email">Email</label>
<input id="email" {...register('email')} />
{errors.email && <p style={{ color: 'red' }}>{errors.email.message}</p>}
</div>
<div>
<label htmlFor="password">Password</label>
<input id="password" type="password" {...register('password')} />
{errors.password && <p style={{ color: 'red' }}>{errors.password.message}</p>}
</div>
<div>
<label htmlFor="confirmPassword">Konfirmasi Password</label>
<input id="confirmPassword" type="password" {...register('confirmPassword')} />
{errors.confirmPassword && <p style={{ color: 'red' }}>{errors.confirmPassword.message}</p>}
</div>
<button type="submit">Daftar</button>
</form>
);
};
export default RegistrationForm;
Penjelasan Kode Komponen:
useForm
: Hook ini adalah inti dari React Hook Form. Kita mengonfigurasinya dengan resolver: zodResolver(registrationSchema)
. Ini memberitahu React Hook Form untuk menggunakan skema Zod kita sebagai aturan validasi.
register
: Fungsi ini kita sebarkan (...register('fieldName')
) ke setiap elemen input
. Ini akan "mendaftarkan" input ke dalam hook, menangani onChange
, onBlur
, dan ref
.
handleSubmit
: Fungsi ini akan membungkus fungsi onSubmit
kita. Ia akan terlebih dahulu menjalankan validasi. Jika validasi berhasil, maka fungsi onSubmit
kita akan dieksekusi dengan data form yang sudah divalidasi. Jika gagal, ia akan menampilkan pesan error.
formState: { errors }
: Objek ini berisi semua pesan error yang dihasilkan dari proses validasi. Kita bisa menggunakannya untuk menampilkan pesan error di bawah setiap input yang tidak valid.
Kesimpulan ????
Dengan menggabungkan React Hook Form dan Zod, Anda dapat membangun form yang tidak hanya andal dan beperforma tinggi tetapi juga sangat mudah untuk dikelola. Pendekatan berbasis skema dari Zod menjaga logika validasi tetap terpusat dan rapi, sementara React Hook Form mengurus sisanya dengan performa yang optimal. Kombinasi ini adalah standar modern untuk manajemen form dalam ekosistem React.