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.
#Step 1: Install 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.
#Step 3: Set up the form component
Let’s create a basic form with fields for email and password:
export default function MyForm() {
return (
<form className="form">
<input className="input" placeholder="email" />
<input className="input" placeholder="password" />
<button type="submit">Submit</button>
</form>
);
}
#Step 4: Add React Hook 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 MyForm() {
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.
#Step 6: Handling form submission
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>;
#Full example
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 MyForm() {
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>
);
}
#Conclusion
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!