Zod는 TypeScript 친화적인 스키마 기반 데이터 검증 라이브러리입니다. React에서는 주로 React Hook Form과 함께 폼 데이터를 검증할 때 많이 사용됩니다.
💡 주요 특징
- 타입 안전성: TypeScript와 강력하게 통합되어 타입을 보장합니다.
- 직관적인 API: 선언적인 방식으로 검증 스키마를 쉽게 정의할 수 있습니다.
- 유연한 검증 규칙: 다양한 검증 규칙 및 커스텀 메시지를 지원합니다.
- 사용이 간편: 빠르게 적용하여 데이터 검증을 간결하게 처리할 수 있습니다.
yarn add zod
# 또는
npm install zod
import { z } from "zod";
const userSchema = z.object({
firstName: z.string().min(1, 'First name is required'),
lastName: z.string().min(1, 'Last name is required')
});
try {
userSchema.parse({ firstName: 'John', lastName: '' });
} catch (e) {
console.log(error);
}
✔️ parse
를 사용하면 검증이 실패할 경우 오류를 발생합니다.
✔️ safeParse
를 사용하면 오류 대신 결과를 객체로 반환합니다.
Zod는 React Hook Form과 함께 사용하면 더욱 강력한 폼 검증을 수행할 수 있습니다.
yarn add @hookform/resolvers
# 또는
npm install @hookform/resolvers
"use client"
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
const signInSchema = z.object({
email: z.string().email({ message: "Invalid email" }).min(1, { message: "Email required" }),
password: z.string().min(8, "Password must be at least 8 characters")
});
const SignInForm = () => {
const { register, handleSubmit, formState } = useForm({
mode: "onChange",
resolver: zodResolver(signInSchema),
});
const onSubmit = async (data) => {
console.log(data);
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} placeholder="Email" />
{formState.errors.email && <p>{formState.errors.email.message}</p>}
<input type="password" {..register("password")} placeholder="Password" />
{formState.errors.password && <p>{formState.errors.password.message}</p>}
<button type="submit" disabled={!formState.isValid}>
Sign In
</button>
</form>
)
}
✔️ zodResolver
를 사용해 Zod와 React Hook Form을 연결할 수 있습니다.
✔️ formState.errors
를 통해 검증 오류 메시지를 표시할 수 있습니다.
✔️ mode: "onChange"
를 설정하면 입력값이 변경될 때마다 검증이 실행됩니다.
const asyncSchema = z.object({
email: z.string().email("Invalid email")
})
const SignInForm = () => {
const { register, handleSubmit, formState } = useForm({
resolver: zodResolver(asyncSchema),
mode: "onBlur",
asyncResolver: async (value) => {
const res = await fetch("/api/validate-email", {
method: "POST",
body: JSON.stringify({ email: values.email })
});
const data = await res.json();
return data.isValid ? { values } : { values: {}, errors: { email: { message: "Email already taken" } } }
}
})
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<input {...register("email")} placehandler="Email" />
{formState.errors.email && <p>{formState.errors.email.message}</p>}
<button type="submit">Sign In</button>
</form>
)
}
✔️ asyncResolver
를 사용하면 서버와 연동하여 검증할 수 있습니다.
✔️ mode: "onBlur"
를 설정하면 입력 필드에서 포커스를 벗어날 때 검증이 실행됩니다.