Effortless Form Handling in React with React Hook Form and Zod.

If you are a web developer then you must have worked with forms and you know how important it is to handle and validate forms correctly for security purpose and having expected input by the user.

In order to make form handling and validation easy, we will be using react-hook-form and zod with a react + vite + typescript project but before lets learn what are this libraries that we will be using.

What is react-hook-form

React Hook Form is a opensource library to handle and validate complex forms to make your life easy. It is fast, easily integrate with react and UI frameworks.

What is Zod

Zod is used for data validation and it works really great with typescript.
You can declare schema and validate it, schema is a broad term however you can say its a datatype with validation in it.

Prerequisites:

I am assuming that you are familiar with react, typescript.

Get started

To get started, we'll create a new React project using Vite and TypeScript. Vite is a modern, fast, and lightweight build tool that makes it easy to set up a React project with TypeScript support.

  1. Create a new React + Typescript project with vite.

     npm create vite@latest my-app -- --template react-ts
     cd my-app
     npm install
    
  2. Install the necessary dependencies.

     npm install react-hook-form zod
    

Now, let's create a simple form component that will register the user to demonstrate the integration of react-hook-form and zod

Make a new file "register.tsx" file
  1. Now first we have to define the type for the data that we will be taking as input from the user. However we will be using zod and we have to define the validation schema also so why write the similar thing again zod is there to make it easy for you and its one of the best things about zod.

     import { useForm } from 'react-hook-form'
     import { z } from 'zod'
    
     // define the validation schema for the form data 
     const formSchema = z.object({
         email: z.string().email(),
         fullName: z.string().min(2, { message: 'Name is too short' }),
         password: z.string().min(8, { message: 'Password is too short' }),
     });
     // zod can automatically infer the typescript type from its schema
     type formDataType = z.infer<typeof formSchema>;
     // register component...
    

We have validation schema and type ready. Now we can move to the next step of using react-hook-form with zod.

  1. To use zod with react-hook-form we will need a resolver which can be installed using npm as follows.

     npm i @hookform/resolvers
    
  2. let start with the Register component.

     // other imports...
     import { zodResolver } from '@hookform/resolvers/zod';
     // schema and type...
    
     const Register = () => {
    
         const {
             register,
             handleSubmit,
             formState: { errors },
         } = useForm<formDataType>({ resolver: zodResolver(formSchema) });
    
         const onSubmit = (data: formDataType) => {
             console.log(data);
             // handle submition 
         };
    
         return (
             <>
                 <form onSubmit={handleSubmit(onSubmit)} >
                     <div>
                         <label htmlFor="full-name">Full Name</label>
                         <input
                             id='full-name'
                             type="text"
                             placeholder='Full name'
                             {...register('fullName')}
                         />
                         {errors.fullName && <p>{errors.fullName.message}</p>}
                     </div>
                     <div>
                         <label htmlFor="email">Email</label>
                         <input
                             id='email'
                             type="email"
                             placeholder='Enter your email...'
                             {...register('email')}
                         />
                         {errors.email && <p>{errors.email.message}</p>}
                     </div>
                     <div>
                         <label htmlFor="password">Password</label>
                         <input
                             id='password'
                             type="password"
                             placeholder='Password...'
                             {...register('password')}
                         />
                         {errors.password && <p>{errors.password.message}</p>}
                     </div>
    
                     <button>
                         Register
                     </button>
    
                 </form>
             </>
         )
     }
    
     export default Register
    

    In the above example code, we use the useForm hook from React Hook Form and pass the zodResolver from @hookform/resolvers/zod as the resolver option. This allows React Hook Form to automatically validate the form data against the Zod schema.

    Inside the form component, we use register function from useForm to bind the form inputs to the form state managed by the react-hook-form , we also display any validation errors using errors from the formState .

    When the form is submitted, the onSubmit function is called with the validated form data, which we can process as needed.

This is a basic example, but it demonstrates how you can leverage the power of React Hook Form and Zod to create efficient and secure form handling in your React applications.

For better code readability it is recommended to put the schema in a different file specially if the form has too many fields and its complex.

In the next blog we will be learning to validate data on server side.

Happy Coding!!