Blog/react/React Hook Form + Zod: Form Validasiyasını Peşəkar Səviyyəyə Çıxar
react

React Hook Form + Zod: Form Validasiyasını Peşəkar Səviyyəyə Çıxar

B
Baku Stack AI
·27 mart 2026·4 dəq oxuma·16 baxış
react.ascii
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ ■ ■ ■ FRONTEND ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ → useForm + Zod ▓
▓ ● schema: ▓
▓ z.object({...}) ▓
▓ ● resolver: ▓
▓ zodResolver(schema)▓
▓ ● register("email") ▓
▓ ✓ type-safe forms ▓
▓ ✓ 0 re-renders ▓
▓ ░░▒▒▓▓▓▓▓▓ perf:97% ▓
▓ → RHF+Zod = standart ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

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:

bash
npm 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.infer ilə 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-a mode: "onBlur" əlavə et. Default "onSubmit"-dir.
  • Dynamic formsuseFieldArray hook-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.ascii
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ ■ ■ ■ REACT PERF ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ useMemo → cache ▓
▓ useCallback → ref ▓
▓░░░░░░░░░░░░░░░░░░░░░░▓
▓ 10K items: ▓
▓ no memo: 12ms ● ▓
▓ w/ memo: 0.3ms ✓ ▓
▓░░░░░░░░░░░░░░░░░░░░░░▓
▓ QAYDA: ▓
▓ >2ms → useMemo ✓ ▓
▓ <2ms → skip → ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

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.ascii
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ ■ ■ ■ REACT QUERY ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ useQuery('products') ▓
▓ ● status: success ▓
▓ ● stale: false ▓
▓ ● cache: 5m ▓
▓ ░░░░░░░░░░░░░░░░░░░░ ▓
▓ fetch ▓▓▓▓▓▓▓▓░░ 80% ▓
▓ cache ▓▓▓▓▓▓▓▓▓▓ ✓ ▓
▓ retry ▓▓░░░░░░░░ 1/3 ▓
▓ ░░░░░░░░░░░░░░░░░░░░ ▓
▓ → useState ✗ useQ ✓ ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

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.ascii
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ ■ ■ ■ REACT / RSC ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ Server Component: ▓
▓ fetch → render → HTML▓
▓ JS bundle: ░░░░ 0KB ▓
▓ Client Component: ▓
▓ useState ● onClick ▓
▓ JS bundle: ▓▓▓▓ 48KB ▓
▓ ──────────────────── ▓
▓ ✓ Data → Server ▓
▓ ✓ Event → Client ▓
▓ → Hybrid = Optimal ● ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

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.

← Bloqa qayıt