So….What is:
React hook form: It is a popular light library to create and manage forms. It is very performative and comes with built-in validation support.
**Zod **: It is a schema validation library that lets you define the shape of your data and validate it at runtime. It makes easier to do validation.
Create a react app with JS or TS whatever you prefer. After that install these packages in a react app:
npm install react-hook-form zod @hookform/resolvers
For javascrit app
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { email, z } from "zod"
const schema = z.object({
id: z.number().optional(),
name: z.string()
.min(1, "Name is required")
.max(30, "Max length should be 30"),
email: z.string()
.email("Please enter valid email"),
age: z.number({
required_error: "Age is required",
invalid_type_error: "Age must be a number"
})
.min(19, "Min value 19")
.max(99, "Max valud 99")
})
export default function App() {
const { handleSubmit, register,reset, formState: { errors, isValid, isDirty } } = useForm({
resolver: zodResolver(schema),
mode: 'onChange',
defaultValues: {
id: 0
}
});
function onSubmit(data) {
console.log(data);
reset();
}
return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<input type="hidden" {...register("id")} />
Name: <input {...register("name")} />
{errors.name && <p>{errors.name.message}</p>}
<br />
Email: <input {...register("email")} />
{errors.email && <p>{errors.email.message}</p>}
< br />
Age: <input type="number" {...register("age", { valueAsNumber: true })} />
{errors.age && <p>{errors.age.message}</p>}
< br />
<button type="submit" disabled={!isDirty || !isValid}>Save</button>
</form>
</>
)
}
For Typescript app:
import { useForm } from "react-hook-form";
import type { SubmitHandler } from "react-hook-form";
import { z } from 'zod';
import { zodResolver } from "@hookform/resolvers/zod";
type IFormInput = z.infer<typeof schema>;
const schema = z.object({
id: z.number(),
firstName: z.string()
.min(1, "First Name is required")
.max(30, "Length of FirstName can not exceed 30 characters"),
lastName: z.string()
.min(1, "Last Name is required")
.max(30, "Length of FirstName can not exceed 30 characters"),
})
export default function PersonForm() {
const { register, handleSubmit, reset, formState: { errors, isValid, isDirty } } = useForm<IFormInput>({
resolver: zodResolver(schema),
mode: 'onChange',
defaultValues: {
id: 0
}
})
const onFormSubmit: SubmitHandler<IFormInput> = (data) => {
console.log(data);
reset();
}
return (
<form className='w-1/4' onSubmit={handleSubmit(onFormSubmit)}>
<input type="hidden" {...register("id")} />
First Name: <input {...register("firstName")} id="fieldgroup-firstName" placeholder="First Name" />
{errors.firstName && <p style={{ 'color': 'red' }}>{errors.firstName.message}</p>}
<p></p>
Last Name: <input {...register("lastName")} id="fieldgroup-lastName" placeholder="Last Name" />
{errors.lastName && <p style={{ 'color': 'red' }}>{errors.lastName.message}</p>}
<p></p>
<button type="reset" onClick={() => reset()}>Reset</button>
<button type="submit" disabled={!isDirty || !isValid}>Submit</button>
</form>
)
}
