If your app interacts with an API, it's crucial to validate inputs before making
any requests. Imagine a sign-up form with fields for email and password. If the
user types "HelloWorld" in the email field, that’s clearly not an email.
While your API might catch it and return an error like "The email must be
valid," it’s more efficient to validate on both the frontend and backend. This
saves time by catching errors before making unnecessary requests. So, let’s dive
into how to set up validation using Zod and
React Hook Form .
First, install the necessary packages:
yarn add react-hook-form zod @hookform/resolvers
Step 2: Define a validation schema with Zod
Now, we’ll create a schema to define our form’s structure and validation rules:
import { z } from " zod " ;
const SignUpSchema = z . object ({
email : z . string () . email () ,
password : z . string () . min ( 3 ) . max ( 20 ) ,
}) ;
type SignUpSchemaType = z . infer <typeof SignUpSchema >;
Here, we’re saying the email
must be a string and a valid email format, and
password
must be a string between 3 and 20 characters.
Let’s create a basic form with fields for email and password:
export default function App () {
return (
< form className = " form " >
< input className = " input " placeholder = " email " />
< input className = " input " placeholder = " password " />
< button type = " submit " > Submit </ button >
</ form >
) ;
}
Now we’ll integrate useForm
from React Hook Form:
import { useForm } from " react-hook-form " ;
import { zodResolver } from " @hookform/resolvers/zod " ;
export default function App () {
const {
register ,
handleSubmit ,
formState : { errors },
} = useForm < SignUpSchemaType > ({
resolver : zodResolver ( SignUpSchema ) ,
}) ;
return (
< form className = " form " >
< input className = " input " placeholder = " email " { ... register ( " email " ) } />
< input
className = " input "
placeholder = " password "
{ ... register ( " password " ) }
/>
< button type = " submit " > Submit </ button >
</ form >
) ;
}
We’ve added useForm
to handle form validation using zodResolver
to connect
our Zod schema.
Step 5: Display validation errors
Next, we’ll show error messages below the inputs if validation fails. For
example, if someone enters "HelloWorld" as their email, it’ll trigger an error:
return (
< form className = " form " >
< input className = " input " placeholder = " email " { ... register ( " email " ) } />
{ errors . email && < span > { errors . email . message} </ span > }
< input className = " input " placeholder = " password " { ... register ( " password " ) } />
{ errors . password && < span > { errors . password . message} </ span > }
< button type = " submit " > Submit </ button >
</ form >
) ;
Now, when there’s an error in either the email or password field, the relevant
error message will display.
Finally, we handle form submission with validation. When the form passes all
checks, the onSubmit
function will execute:
const onSubmit : SubmitHandler < SignUpSchemaType > = ( data ) => {
console . log ( data ) ;
} ;
< form onSubmit = { handleSubmit ( onSubmit ) } className = " form " >
{ /* form fields */ }
</ form > ;
Here’s the complete code for reference:
import { z } from " zod " ;
import { useForm , SubmitHandler } from " react-hook-form " ;
import { zodResolver } from " @hookform/resolvers/zod " ;
const SignUpSchema = z . object ({
email : z . string () . email () ,
password : z . string () . min ( 3 ) . max ( 20 ) ,
}) ;
type SignUpSchemaType = z . infer <typeof SignUpSchema >;
export default function App () {
const {
register ,
handleSubmit ,
formState : { errors },
} = useForm < SignUpSchemaType > ({
resolver : zodResolver ( SignUpSchema ) ,
}) ;
const onSubmit : SubmitHandler < SignUpSchemaType > = ( data ) => {
console . log ( data ) ;
} ;
return (
< form onSubmit = { handleSubmit ( onSubmit ) } className = " form " >
< input className = " input " placeholder = " email " { ... register ( " email " ) } />
{ errors . email && < span > { errors . email . message} </ span > }
< input
className = " input "
placeholder = " password "
{ ... register ( " password " ) }
/>
{ errors . password && < span > { errors . password . message} </ span > }
< button type = " submit " > Submit </ button >
</ form >
) ;
}
That’s it! With Zod and React Hook Form, you can easily set up form validation
in your React applications. For more advanced features, check out their
documentation . Thanks for
reading!