ساخت فرم در React با React Hook Form و اعتبارسنجی فرم با Zod

استفاده از فریمورک ها و کتابخانه های جاوا اسکریپت برای تولید صفحات پویا بسیار پر طرفدار شده و React به عنوان پرکاربردترین کتابخانه ساخت Frontend مورد توجه بسیاری از توسعه دندگان قرارگرفته است. اما در برنامه نویسی، همیشه استفاده از امکانات موجود فریمورک ها و کتابخانه ها به تنهایی برای پروژه های متوسط و بزرگ کافی نیست و با بزرگ تر شدن پروژه و پیچیدگی کار، استفاده از ابزارهایی برای سرعت بخشیدن به کار بسیار پر اهمیت می شود.

برای ساخت فرم هایی پویاتر با قابلیت اعتبارسنجی در React می توان از ابزارهایی مثل React Hook Form و Zod استفاده کرد. با این دو پکیج می توان فرم ها را ساده تر ایجاد، مدیریت و اعتبارسنجی کرد اما چگونه باید از این ابزار در پروژه React استفاده کنیم؟ در ادامه با ما همراه باشید.

ساخت فرم در React

ابتدا یک فرم ورود ساده در React ایجاد می کنیم و سپس پکیج های مورد نظرمان را اضافه و تغییرات را بررسی می کنیم. برای این کار ابتدا یک پروژه React با تایپ اسکریپت ایجاد کنید.

npm create vite@latest react-app -- --template react-ts

بعد از نصب Vite پوشه react-app را باز کنید و دستورات زیر را اجرا کنید:

cd react-app
npm install
npm run dev

در پوشه src یک فایل به نام App.tsx مشاهده می کنید که محل شروع کار ماست.

در VS Code پوشه react-app را با کنید و بعد فایل App.tsx را باز کنید و کل محتویات این فایل را پاک کنید و کد زیر را جایگزین کنید تا یک فایل تمیز برای شروع کار داشته باشیم:

const App = () => {
  return;
  <>form</>;
};

export default App;

در ادامه یک فرم ساده با React قرار داده شده که برای این آموزش استفاده می شود اما می توان برای فرم های پیچیده تر هم به همین روش عمل کرد.

import React, { useState } from "react";

const App: React.FC = () => {
  // State for form inputs
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  // Handle form submission
  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    console.log({ email, password });
  };

  return (
    <div style={{ maxWidth: "400px", margin: "0 auto", padding: "20px" }}>
      <h2>Login</h2>
      <form onSubmit={handleSubmit}>
        <div style={{ marginBottom: "10px" }}>
          <label htmlFor="email" style={{ display: "block", marginBottom: "5px" }}>Email:</label>
          <input
            type="email"
            id="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
            style={{ width: "100%", padding: "8px", boxSizing: "border-box" }}
          />
        </div>

        <div style={{ marginBottom: "10px" }}>
          <label htmlFor="password" style={{ display: "block", marginBottom: "5px" }}>Password:</label>
          <input
            type="password"
            id="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
            style={{ width: "100%", padding: "8px", boxSizing: "border-box" }}
          />
        </div>

        <button
          type="submit"
          style={{
            backgroundColor: "#4CAF50",
            color: "white",
            padding: "10px 15px",
            border: "none",
            borderRadius: "4px",
            cursor: "pointer",
          }}
        >
          Login
        </button>
      </form>
    </div>
  );
};

export default App;

در کد بالا ما دو State ساده برای ایمیل و کلمه عبور تعریف کردیم و با ایجاد دو فیلد ورودی این Stateها را صدا زدیم. یک دکمه هم برای رویداد ثبت فرم تعریف شد که تابع handleSubmit را اجرا می کند که در نهایت مقادیر ایمیل و کلمه عبوری که کاربر وارد کرده را در کنسول نمایش می دهد.

این فرم هیچ قابلیت اعتبارسنجی ندارد و صرفا می تواند با هر داده ای ارسال شود. در برنامه نویسی این یعنی خودکشی! برای حل این مشکل ابتدا از اعتبارسنجی فرم شروع می کنیم.

اعتبارسنجی فرم در React با Zod

حالا که ساخت فرم در React کامل شده برای اعتبارسنجی فرم با Zod ابتدا باید پکیج Zod را نصب کنید. برای نصب از دستور زیر استفاده کنید:

npm install zod

حالا باید Zod را به فایل App.tsx اضافه کنیم و تغییراتی در فرم ایجاد کنیم. ابتدا Zod را صدا بزنید:

import { z } from "zod";

بعد کد زیر را در بدنه تابع وارد کنید:

// Zod schema for validation
  const loginSchema = z.object({
    email: z.string().email("Invalid email address"),
    password: z.string().min(6, "Password must be at least 6 characters long"),
  });

کد بالا یک الگو (schema) برای فرم ایجاد می کند؛ اگر اطلاعات ورودی کاربر از چارچوب الگو خارج باشد فرم اعتبارسنجی نخواهد شد در غیر این صورت اعتبارسنجی تکمیل شده و داده ها ارسال می شود.

در این مرحله برای نمایش خطا در اعتبارسنجی، تابع handleSubmit را به صورت زیر ویرایش کنید:

// Handle form submission
  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    const result = loginSchema.safeParse({ email, password });

    if (!result.success) {
      console.error(result.error.format());
    } else {
      console.log("Form submitted successfully", result.data);
    }
  };

ساخت فرم با React Hook Form

ساخت فرم در React و اعتبارسنجی فرم با Zod تکمیل شد اما اگر فرم پیچیده تر بود چطور؟ به همین راحتی امکان اعتبارسنجی و حتی ایجاد فرم وجود نداشت. برای حل این مشکل در پروژه های متوسط و بزرگ از پکیج React Hook Form استفاده می کنیم. ابتدا پکیج و هماهنگ کننده آن را Zod را نصب کنید:

npm install react-hook-form
npm i @hookform/resolvers

سپس React Hook Form را به پروژه اضافه کنید:

import React from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";

توجه کنید در این روش از State استفاده نمی کنیم. همچنین برای ارتباط Zod با React Hook Form پکیج @hookform/resolvers را نصب کردیم.

برای ایجاد فرم با React Hook Form ابتدا کد زیر را بعد از کد الگوی Zod قرار دهید:

// React Hook Form setup
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(loginSchema),
  });

تابع handleSubmit را حذف کنید و تابع onSubmit را جایگزین کنید:

// Handle form submission
  const onSubmit = (data: any) => {
    console.log("Form submitted successfully", data);
  };

سپس ساختار فرم را به صورت زیر تغییر دهید:

<div style={{ maxWidth: "400px", margin: "0 auto", padding: "20px" }}>
      <h2>Login</h2>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div style={{ marginBottom: "10px" }}>
          <label htmlFor="email" style={{ display: "block", marginBottom: "5px" }}>Email:</label>
          <input
            type="email"
            id="email"
            {...register("email")}
            style={{ width: "100%", padding: "8px", boxSizing: "border-box" }}
          />
          {errors.email && (
            <span style={{ color: "red" }}>{errors.email.message}</span>
          )}
        </div>

        <div style={{ marginBottom: "10px" }}>
          <label htmlFor="password" style={{ display: "block", marginBottom: "5px" }}>Password:</label>
          <input
            type="password"
            id="password"
            {...register("password")}
            style={{ width: "100%", padding: "8px", boxSizing: "border-box" }}
          />
          {errors.password && (
            <span style={{ color: "red" }}>{errors.password.message}</span>
          )}
        </div>

        <button
          type="submit"
          style={{
            backgroundColor: "#4CAF50",
            color: "white",
            padding: "10px 15px",
            border: "none",
            borderRadius: "4px",
            cursor: "pointer",
          }}
        >
          Login
        </button>
      </form>
    </div>

در این مرحله تابع handleSubmit که توسط React Hook Form فراخوانی می شود بعد از ثبت فرم تابع onSubmit را فراخوانی کرده و پس از عملیات اعتبارسنجی نتیجه نمایش داده می شود.

نکته قابل توجه در اینجا تغییرات فیلدهای فرم است. برای مثال فیلد ایمیل را مشاهده کنید:

<input
            type="email"
            id="email"
            {...register("email")}
            style={{ width: "100%", padding: "8px", boxSizing: "border-box" }}
          />
          {errors.email && (
            <span style={{ color: "red" }}>{errors.email.message}</span>
          )}

در این فیلد مقدار value و onChange به {…register(“email”)} تغییر کرده. همچنین برای اعتبارسنجی یک شرط زیر فیلد اضافه شده است:

{errors.email && (
            <span style={{ color: "red" }}>{errors.email.message}</span>
          )}

حالا با وارد کردن مقادیر اشتباه می توان صحت اعتبارسنجی و عملکرد فرم را بررسی کرد.

کد نهایی برای راحتی در زیر قرار داده شده است:

import React from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";

const App: React.FC = () => {
  // Zod schema for validation
  const loginSchema = z.object({
    email: z.string().email("Invalid email address"),
    password: z.string().min(6, "Password must be at least 6 characters long"),
  });

  // React Hook Form setup
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(loginSchema),
  });

  // Handle form submission
  const onSubmit = (data: any) => {
    console.log("Form submitted successfully", data);
  };

  return (
    <div style={{ maxWidth: "400px", margin: "0 auto", padding: "20px" }}>
      <h2>Login</h2>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div style={{ marginBottom: "10px" }}>
          <label htmlFor="email" style={{ display: "block", marginBottom: "5px" }}>Email:</label>
          <input
            type="text"
            id="email"
            {...register("email")}
            style={{ width: "100%", padding: "8px", boxSizing: "border-box" }}
          />
          {errors.email && (
            <span style={{ color: "red" }}>{errors.email.message}</span>
          )}
        </div>

        <div style={{ marginBottom: "10px" }}>
          <label htmlFor="password" style={{ display: "block", marginBottom: "5px" }}>Password:</label>
          <input
            type="password"
            id="password"
            {...register("password")}
            style={{ width: "100%", padding: "8px", boxSizing: "border-box" }}
          />
          {errors.password && (
            <span style={{ color: "red" }}>{errors.password.message}</span>
          )}
        </div>

        <button
          type="submit"
          style={{
            backgroundColor: "#4CAF50",
            color: "white",
            padding: "10px 15px",
            border: "none",
            borderRadius: "4px",
            cursor: "pointer",
          }}
        >
          Login
        </button>
      </form>
    </div>
  );
};

export default App;

جمع بندی

برای ساخت فرم در React با قابلیت هایی مثل اعتبارسنجی پیشرفته و امکان مدیریت آسان تر در React می توان از ابزارهایی مانند React Hook Form برای ایجاد فرم و Zod برای اعتبارسنجی فرم در React استفاده کرد. ساده شدن فرایند اعتبارسنجی به واسطه الگوها و ایجاد راحت تر فرم با این دو پکیج و همچنین هماهنگی آنها یک برتری قابل توجه نسبت به استفاده از Stateها و امکانات پیشفرض React فراهم می کند.

لینک مطلب

مطالب جدید