DEV Community

Cover image for Simplifying Form Validation: React Hook Form vs Traditional Methods
Lingaraj H U
Lingaraj H U

Posted on

Simplifying Form Validation: React Hook Form vs Traditional Methods

Form validation is a crucial aspect of web development, ensuring data integrity and enhancing user experience. In the React ecosystem, we've seen a significant evolution in how we handle forms and their validation.

  • In this blog, we'll compare two approaches: traditional form validation and the modern React Hook Form library.
  • By examining these methods side by side, we'll discover why React Hook Form has become a go-to solution for many developers.

Traditional Form Validation in React

  • Let's start by looking at a traditional approach to form validation in React:
import React, { useState } from "react";

const SimpleForm = () => {

  const [formData, setFormData] = useState({
    firstName: "",
    lastName: "",
    email: "",
    password: "",
    // ... other fields
  });
  const [errors, setErrors] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData({
      ...formData,
      [name]: value,
    });
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setIsSubmitting(true);
    const newErrors = {};

    // Validation logic
    if (!formData.firstName) newErrors.firstName = "First Name is Required";

    if (!formData.lastName) newErrors.lastName = "Last Name is Required";

    if (!formData.email.match(/^\S+@\S+$/i)) newErrors.email = "Invalid email address";

    if (!formData.password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/)) newErrors.password = "Invalid password";

    // ... more validation rules

    if (Object.keys(newErrors).length > 0) {
      setErrors(newErrors);
      return;
    }

    // Submit form data
    try {
      const response = await simulateApiCall(formData);
      console.log("Success: ", response);
    } catch (error) {
      console.error(error);
      setError({ root: error.message });
    } finally {
      setIsSubmitting(false)
    }

  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="firstName"
        value={formData.firstName}
        onChange={handleChange}
      />
      {errors.firstName && <p>{errors.firstName}</p>}

      <input
        name="lastName"
        value={formData.lastName}
        onChange={handleChange}
      />
      {errors.lastName && <p>{errors.lastName}</p>}      

      <input
        name="email"
        value={formData.email}
        onChange={handleChange}
      />
      {errors.email && <p>{errors.email}</p>}


      <input
        type="password"
        name="password"
        value={formData.password}
        onChange={handleChange}
      />
      {errors.password && <p>{errors.password}</p>}

      {/* More form fields */}

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? "Submitting..." : "Submit"}
      </button>
    </form>
  );
};
Enter fullscreen mode Exit fullscreen mode

In this traditional approach

  • We manage form state and error state separately using the useState hook.
  • We manually handle changes to form fields and implement custom validation logic in the handleSubmit function.

While this works, it involves a lot of boilerplate code and can become cumbersome for larger forms.

Enter React Hook Form

  • Now, let's see how we can achieve the same result using React Hook Form:

Installation

npm install react-hook-form
Enter fullscreen mode Exit fullscreen mode
import React from "react";

// useForm is the hook which is given by react-hook-form
import { useForm } from "react-hook-form";

const ReactHookForm = () => {

  const {
    register,
    handleSubmit,
    setError,
    formState: { errors, isSubmitting },
  } = useForm();

  const onSubmit = (data) => {
    // Submit form data
    try {
      const response = await simulateApiCall(formData);
      console.log("Success: ", response);
    } catch (error) {
      console.error(error);
      setError({ root: error.message });
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...register("firstName", { required: "First Name is required" 
        })}
      />

      {errors.firstName && <p>{errors.firstName.message}</p>}

      <input
        {...register("lastName", { required: "Last Name is required" 
        })}
      />

      {errors.lasttName && <p>{errors.lasttName.message}</p>}      

      <input
        {...register("email", {
          required: "Email is required",
          pattern: { value: /^\S+@\S+$/i, message: "Invalid email address" }
        })}
      />

      {errors.email && <p>{errors.email.message}</p>}

      <input
        {...register("password", { required: "First Name is required",
         pattern: { value: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/, message: "Invalid password"}
        })}
      />

      {errors.firstName && <p>{errors.firstName.message}</p>}      

      {/* More form fields */}

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? "Submitting..." : "Submit"}
      </button>

    </form>
  );
};
Enter fullscreen mode Exit fullscreen mode

The Simplicity of React Hook Form

  • Reduced Boilerplate: React Hook Form eliminates the need for manual state management. No more useState for form data and errors.

  • Declarative Validation: Instead of writing imperative validation logic, we declare our validation rules right in the register function. This makes the code more readable and maintainable.

  • Automatic Error Handling: React Hook Form automatically tracks errors and provides them through the errors object, eliminating the need for manual error state management.

  • Performance: By leveraging uncontrolled components, React Hook Form minimizes re-renders, leading to better performance, especially for large forms.

  • Easy Integration: The register function seamlessly integrates with your existing input elements, requiring minimal changes to your JSX.

  • Built-in Validation: Common validation rules like required, min, max, pattern are built-in, reducing the need for custom validation functions.

  • TypeScript Support: React Hook Form provides excellent TypeScript support out of the box, enhancing type safety in your forms.

To understand the how to handle react-hook-form in typescript with more input fileds

  • While traditional form handling in React gives you fine-grained control, it often leads to verbose code that can be hard to maintain.

  • React Hook Form simplifies this process significantly, providing a more declarative and efficient way to handle forms and their validation.

Thank you for reading... hope you learnt something new today :)

Top comments (0)