React Hook Form と Zod を導入し、バリデーション付きフォームを簡単に作成する手順をまとめました。
ぜひフォーム画面に導入してみてください!
📌 はじめに
React Hook Formとは?
- Reactのフォームライブラリ
- フォームの値・状態(入力値、エラー、送信状態など)を管理しやすくする
- 再レンダーが少なく高速
- register でフォーム要素を簡単に登録
- バリデーション機能を持っているが、外部ライブラリとも連携できる
Zodとは?
- 型安全なバリデーションライブラリ
- スキーマ(型やルール)を定義し、その通りにデータが正しいかをチェックできる
- TypeScriptと相性が良く、型を自動生成できる(z.infer)
- バリデーションルールを一元管理できる
- 他のフォームライブラリ(例:React Hook Form)と組み合わせやすい
💡 よくある組み合わせ
-
Zodでスキーマ定義(何が必須・どの形式か) -
React Hook Formのresolverにそのスキーマを渡し、フォーム送信時に自動チェック
`zod`と組み合わせることで、 - 型とルールを1か所に集約できる - エラーメッセージを簡単に実装できる - 型を自動生成できる などのメリットがあります。
📌 使用ツール
- React Hook Form
- Zod
- Next.js(App Router)/ TypeScript
📌 導入手順
① パッケージ導入
# npm
npm i react-hook-form zod @hookform/resolvers
# or yarn
yarn add react-hook-form zod @hookform/resolvers
# or pnpm
pnpm add react-hook-form zod @hookform/resolvers
② スキーマ & 型の用意(Zod)
username / email / password の最小限スキーマ。z.infer で型も自動生成します。
実装例↓
"use client";
import { z } from "zod";
export const signUpSchema = z.object({
username: z.string().trim().min(1, "ユーザー名を入力してください").max(50, "50文字以内で入力してください"),
email: z.string().trim().email("メールアドレスの形式ではありません"),
password: z
.string()
.min(8, "パスワードは8文字以上です")
.max(100, "100文字以内で入力してください"),
});
export type SignUpForm = z.infer<typeof signUpSchema>;
③ フォーム実装(React Hook Form × Zod Resolver)
実装例↓
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { signUpSchema, type SignUpForm } from "./schema";
export default function SignUpPage() {
const { register, handleSubmit, formState: { errors } } = useForm<SignUpForm>({
resolver: zodResolver(signUpSchema)
});
const onSubmit = (data: SignUpForm) => alert(JSON.stringify(data));
return (
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4 max-w-sm mx-auto mt-20">
<div>
<input placeholder="Username" {...register("username")} className="border p-2 w-full" />
<p className="text-red-500 text-sm">{errors.username?.message}</p>
</div>
<div>
<input placeholder="Email" {...register("email")} className="border p-2 w-full" />
<p className="text-red-500 text-sm">{errors.email?.message}</p>
</div>
<div>
<input type="password" placeholder="Password" {...register("password")} className="border p-2 w-full" />
<p className="text-red-500 text-sm">{errors.password?.message}</p>
</div>
<button type="submit" className="bg-blue-500 text-white px-4 py-2 rounded">Sign Up</button>
</form>
);
}
📌 まとめ
-
Zodでスキーマ定義 →zodResolverでReact Hook Formに適用 -
errors.xxx?.messageでエラー表示
以上で簡単にバリデーション付きフォームを実装できます。
ぜひ、参考にしてみてください!