Schema based form validation in React JS using React Hook Form and Zod library
Suresh Hariharan
Posted on June 11, 2023
Form Validation
Form validation is an essential aspect of website development that ensures the data entered by users into web forms is accurate, complete, and follows the specified format. It helps maintain data integrity, improves user experience, and prevents potential issues resulting from incorrect or malicious input.
Zod
The Zod library is a TypeScript-first runtime validation library that provides a simple and expressive way to validate data objects against predefined schemas. It focuses on type safety and usability, making it easier to validate and enforce data integrity in TypeScript projects.
In ZOD we can only define data constraints such as minLength, maxLength we cannot define field constraints such as reset , required etc..
Setup the project
Create project using vite
`npm create vite`
Enter the application name
`Project name: "your application name"`
Select react form below list
`❯ Vanilla
Vue
React
Preact
Lit
Svelte
Others`
Select the programming language
In this example i will be using typescript and bootstrap for styling this component
❯ TypeScript
TypeScript + SWC
JavaScript
JavaScript + SWC
Now execute the following commands one by one to run the application
cd summa
npm install
npm run dev
After executing the above steps your application will be running on localhost:5173
The running application will be like this,
Before moving on further install the following libraries in your application by using the commands
npm install react-hook-form
npm i zod
npm i @hook-form/resolvers
Zod resolvers are used to handle asynchronous validation and transformation of data using the Zod library. While Zod itself provides powerful and flexible schema validation capabilities, it doesn't handle asynchronous operations by default. Zod resolvers fill this gap by providing a convenient way to perform asynchronous validation tasks.
Create a form component in your application
create a basic form in your component
<form>
<div className="mb-3">
<label htmlFor="name" className="form p-3">
name
</label>
<input
id="name"
type="text"
className="form.control"
/>
</div>
<div>
<label htmlFor="age" className="form p-3">
age
</label>
<input
/>
</div>
<button className="btn btn-primary mx-3" type="submit">
Submit
</button>
</form>
In zod the validation will be done based on the schema we provide. So after creating a form create a schema for the inputs that will be accepted in the form.
Schema:Schemas are nothing but a set of constraints of the type of data that the user will be passing as input in the form.In other words schemas are the datatypes for the from
In react Schemas should be defined after the import statements in your component.
Schema declaration for our form
const schema = z.object({
name: z.string().min(3),
age: z.number().min(18),
});
Define a Type and pass this schema as an interface in the component
type formData = z.infer<typeof schema>;
We can define the types of the field data as methods and can also define validation constraints .So that later in form hook we can use this validation as references.
Now as the next step use the useForm hook that we installed earlier
const {
register,
handleSubmit,
formState: { errors },
} = useForm<formData>({ resolver: zodResolver(schema) });
Let's understand whats happening here, the useForm has couple of predefined methods that we destructured as ,
"register"- The register method is use to register our form field in the hook so that later we can reference it for validation, this method takes the name attribute of the input tag as an argument
"handleSubmit"- This method takes care of all form submission tasks for us, we only need to simply reference in onSubmit event listener.
"formState"- This method keeps track of our form field state and notifies to handle any errors.
Thats enough of the theory stuff, let's see the code in action.
Define an submit function and call it in handleSubmit() in the form tag.
const submit = (data: FieldValues) => {
console.log(data);
};
<form onSubmit={handleSubmit(submit)}>
Use the register method in the input tag and set validation conditions such as 'required'
{...(register("name"), { required: true})}
In zod we can also display custom Error messages or default messages that are predefined in the zod library
We can do this by using simple logic as ,
{errors.name && <p>{errors.name.message}</p>}
And finally, after all the above steps are implemented the final code looks like this,
import { useForm, FieldValues } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
const schema = z.object({
name: z.string().min(3),
age: z.number().min(18),
});
type formData = z.infer<typeof schema>;
const form = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<formData>({ resolver: zodResolver(schema) });
const submit = (data: FieldValues) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(submit)}>
<div className="mb-3">
<label htmlFor="name" className="form p-3">
name
</label>
<input
{...(register("name"), { required: true})}
id="name"
type="text"
name=""
className="form.control"
/>
{errors.name && <p>{errors.name.message}</p>}
</div>
<div>
<label htmlFor="age" className="form p-3">
age
</label>
<input
{...register("age")}
id="age"
type="number"
className="form.control"
/>
</div>
<button className="btn btn-primary mx-3" type="submit">
Submit
</button>
</form>
);
};
export default form;
Thats all it takes to create a form with schema based validation using react-hook-form and zod library.
Posted on June 11, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
June 11, 2023