React Hook Form + Zod: Form Validasiyasını Peşəkar Səviyyəyə Çıxar
Formik və ya manual validasiya ilə vaxt itirirsən? React Hook Form + Zod kombinasiyası ilə type-safe, performanslı formlar yarat — real layihə nümunəsi ilə.
React Hook Form + Zod: Form Validasiyasını Peşəkar Səviyyəyə Çıxar
Salam, developer! Əgər hələ də onChange handler-ləri ilə manual validasiya yazırsan və ya Formik-in re-render problemləri ilə mübarizə aparırsan, bu məqalə sənin üçündür. Bu gün Bakıda işləyən front-end developer-lərin əksəriyyətinin portfolio-suna və ya iş layihələrinə əlavə edə biləcəyi ən güclü form validasiya stack-indən danışacağıq: React Hook Form + Zod.
Niyə Bu Kombinasiya?
Əvvəlcə kontekst verək. npm trends statistikasına görə, 2026-cı ilin mart ayına qədər React Hook Form həftəlik 7 milyondan çox yükləmə ilə form kitabxanaları arasında liderdir. Zod isə həftəlik 12 milyondan çox yükləmə ilə runtime validation dünyasının ən populyar həllidir.
Bu ikisini birlikdə istifadə etməyin üstünlükləri:
- Type safety — Zod schema-dan TypeScript tipləri avtomatik çıxarılır
- Performans — React Hook Form uncontrolled komponentlər istifadə edir, re-render minimal olur
- DRY prinsipi — validasiya qaydalarını bir dəfə yazırsan, həm client, həm server tərəfdə istifadə edirsən
- Developer Experience — kod oxunaqlı, test edilə bilən və maintain edilə bilən olur
Bakıdakı şirkətlərə — istər Kapital Bank-ın digital komandası olsun, istər PASHA Holding-in texnoloji layihələri, istər Azerconnect kimi telekom şirkətləri — müsahibələrdə TypeScript + modern form handling bilmək artıq "nice to have" deyil, "must have"-dir. 1500-3500 AZN arası maaş verən mid-level React pozisiyalarının demək olar ki, hamısında bu stack-i görmək mümkündür.
Quraşdırma
Layihənə bu paketləri əlavə et:
bashnpm install react-hook-form zod @hookform/resolvers
@hookform/resolvers paketi React Hook Form ilə Zod arasında körpü rolunu oynayır. Onsuz bu ikisi bir-birindən xəbərsizdir.
Real Nümunə: İstifadəçi Qeydiyyat Formu
Gəl praktiki bir nümunə yazaq. Fərz edək ki, Bakıda bir fintech startup üçün qeydiyyat formu hazırlayırsan. Formda ad, e-poçt, telefon nömrəsi və şifrə sahələri var.
1. Zod Schema-nı Yaz
typescript// schemas/registerSchema.ts import { z } from "zod"; export const registerSchema = z.object({ fullName: z .string() .min(3, "Ad minimum 3 simvol olmalıdır") .max(50, "Ad maksimum 50 simvol ola bilər"), email: z .string() .email("Düzgün e-poçt ünvanı daxil edin"), phone: z .string() .regex( /^\+994(50|51|55|70|77|99)\d{7}$/, "Nömrə +994XX1234567 formatında olmalıdır" ), password: z .string() .min(8, "Şifrə minimum 8 simvol olmalıdır") .regex( /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, "Şifrədə böyük hərf, kiçik hərf və rəqəm olmalıdır" ), confirmPassword: z.string(), }).refine((data) => data.password === data.confirmPassword, { message: "Şifrələr uyğun gəlmir", path: ["confirmPassword"], }); export type RegisterFormData = z.infer<typeof registerSchema>;
Diqqət et: z.infer<typeof registerSchema> — bu sətir schema-dan avtomatik TypeScript tipi çıxarır. Yəni ayrıca interface yazmağa ehtiyac yoxdur. Bir mənbə, iki istifadə.
Həmçinin phone sahəsindəki regex Azərbaycan nömrə formatına uyğundur — +994 prefiksi və operator kodları (50, 51, 55, 70, 77, 99) daxildir.
2. Form Komponentini Yarat
tsx// components/RegisterForm.tsx import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { registerSchema, RegisterFormData } from "../schemas/registerSchema"; export default function RegisterForm() { const { register, handleSubmit, formState: { errors, isSubmitting }, } = useForm<RegisterFormData>({ resolver: zodResolver(registerSchema), defaultValues: { fullName: "", email: "", phone: "+994", password: "", confirmPassword: "", }, }); const onSubmit = async (data: RegisterFormData) => { // API call — məsələn, POST /api/register console.log("Validasiya keçdi:", data); // await fetch("/api/register", { method: "POST", body: JSON.stringify(data) }); }; return ( <form onSubmit={handleSubmit(onSubmit)} noValidate> <div> <label htmlFor="fullName">Ad Soyad</label> <input id="fullName" {...register("fullName")} /> {errors.fullName && ( <span className="error">{errors.fullName.message}</span> )} </div> <div> <label htmlFor="email">E-poçt</label> <input id="email" type="email" {...register("email")} /> {errors.email && ( <span className="error">{errors.email.message}</span> )} </div> <div> <label htmlFor="phone">Telefon</label> <input id="phone" type="tel" {...register("phone")} /> {errors.phone && ( <span className="error">{errors.phone.message}</span> )} </div> <div> <label htmlFor="password">Şifrə</label> <input id="password" type="password" {...register("password")} /> {errors.password && ( <span className="error">{errors.password.message}</span> )} </div> <div> <label htmlFor="confirmPassword">Şifrə Təkrarı</label> <input id="confirmPassword" type="password" {...register("confirmPassword")} /> {errors.confirmPassword && ( <span className="error">{errors.confirmPassword.message}</span> )} </div> <button type="submit" disabled={isSubmitting}> {isSubmitting ? "Göndərilir..." : "Qeydiyyat"} </button> </form> ); }
Bu qədər. Heç bir useState, heç bir manual if-else validasiya zənciri yoxdur. zodResolver hər şeyi avtomatik idarə edir.
Niyə Bu Stack İş Müsahibəsində Fərq Yaradır?
Bakıda front-end müsahibələrində tez-tez belə suallar verilir:
- "Formik ilə React Hook Form arasındakı fərq nədir?" → Cavab: RHF uncontrolled approach ilə daha az re-render yaradır.
- "Type safety-ni necə təmin edirsən?" → Cavab: Zod schema-dan
z.inferilə tip çıxarıram, əlavə interface yazmıram. - "Server-side validasiya ilə client-side-ı necə sinxronlaşdırırsan?" → Cavab: Eyni Zod schema-nı hər iki tərəfdə istifadə edirəm.
Bu sualların hər üçünə hazır cavab vermək, sənin 2000-3000 AZN maaş diapazonundakı pozisiyaya uyğun olduğunu göstərir.
Əlavə Tövsiyələr
mode: "onBlur"— istifadəçi sahədən çıxanda validasiya işləsin istəyirsənsə,useForm-amode: "onBlur"əlavə et. Default"onSubmit"-dir.- Dynamic forms —
useFieldArrayhook-u ilə dinamik sahələr (məsələn, bir neçə ünvan) əlavə edə bilərsən. - Server errors — API-dən gələn xətaları
setError("email", { message: "Bu e-poçt artıq istifadə olunur" })ilə forma inject edə bilərsən. - Zod
.transform()— məsələn, telefon nömrəsindən boşluqları silmək və ya e-poçtu lowercase etmək üçün.transform(val => val.toLowerCase())istifadə et.
Nəticə
React Hook Form + Zod kombinasiyası 2026-da React ekosistemində form handling üçün de-facto standartdır. Bu stack-i öyrənmək sənə həm kod keyfiyyəti, həm performans, həm də iş bazarında rəqabət üstünlüyü verir.
Layihələrini GitHub-a yüklə, bu pattern-i istifadə et və LinkedIn-də paylaş. Bakıdakı recruiter-lər baxır — inan, baxır.
Sualın varsa, şərhlərdə yaz. Növbəti məqalədə React Hook Form + Zod + Server Actions (Next.js) inteqrasiyasından danışacağıq. Görüşənədək! 🚀
Oxşar məqalələr
React-da Performans: useMemo və useCallback — Nə Vaxt Lazımdır?
useMemo və useCallback hər yerə yazmaq reflex olub? Gəl birlikdə anlayaq: bu hook-lar nə vaxt həqiqətən lazımdır, nə vaxt isə əksinə — zərərdir.
React Query ilə Server State: useState-dən Qurtuluş Yolu
Hələ də API datanı useState + useEffect ilə idarə edirsən? React Query ilə server state-i necə peşəkar səviyyədə idarə etməyi öyrən.
React Server Components — Nə Vaxt İstifadə Etməli, Nə Vaxt Yox?
RSC hər yerə lazım deyil. Bu məqalədə real kod nümunələri ilə Server Components-in nə vaxt performans artırdığını, nə vaxt isə əngəl olduğunu izah edirik.