今回は、React Hook FormとZodを活用して、複数のフォームフィールドのバリデーションを効率的に行う方法について詳しく解説します。
開発環境
- react-hook-form: v7.15.4
- zod: v3.11.6
はじめに
React Hook Formは、Reactでのフォームバリデーションを効率的に行うためのライブラリです。React Hook Formを使用することで、フォームフィールドの値の取得、バリデーション、エラーメッセージの表示などを簡単に実装できます。
一方、ZodはTypeScript向けのバリデーションライブラリで、簡単にバリデーションスキーマを定義でき、カスタムバリデーションもサポートしています。React Hook FormとZodを組み合わせることで、簡潔で理解しやすいコードで、複雑なバリデーションを含むフォームを実装することができます。
Zodでの一つのフィールドのバリデーション
まず、一つのフィールドに対するバリデーションをZodを使ってどのように作成するか見てみましょう。ここでは、firstName
というフィールドが空文字でないことを確認するバリデーションを設定しています。
import { z } from 'zod';
export const profileSchema = z
.object({
firstName: z.string().nonempty('名は入力必須項目です'),
// 他のフィールド...
});
Zodでの複数フィールドにまたがるバリデーション
一つのフィールドに対するバリデーションができたら、次は複数フィールドにまたがるバリデーションを設定してみましょう。以下の例では、同じくlastName
にもバリデーションを設定し、さらにfirstName
とlastName
のどちらかが空でないことを確認するバリデーションを追加します。
export const profileSchema = z
.object({
lastName: z.string().nonempty('姓は入力必須項目です'),
firstName: z.string().nonempty('名は入力必須項目です'),
// 他のフィールド...
})
.refine((data) => data.lastName !== '' || data.firstName !== '', {
path: ['lastName', 'firstName'],
message: '姓と名のどちらか一つは入力してください'
});
React Hook Formでのエラーメッセージの表示
Zodで定義したバリデーションスキーマをReact Hook Formに組み込み、エラーメッセージを表示する方法を見てみましょう。
まず、useForm
フックから得られるregister
とerrors
を利用します。register
はフォームフィールドをReact Hook Formに登録するための関数で、errors
は各フィールドのエラー情報を含むオブジェクトです。
次に、各フォームフィールドにregister
を割り当て、エラーがある場合はerrors
から対応するエラーメッセージを表示します。
import { useForm } from "react-hook-form";
import { profileSchema } from "./validation";
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(profileSchema)
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName")} />
{errors.firstName && <p>{errors.firstName.message}</p>}
<input {...register("lastName")} />
{errors.lastName && <p>{errors.lastName.message}</p>}
{/* 他のフィールド... */}
<input type="submit" />
</form>
);
上記のコードにより、各フォームフィールドがバリデーションに失敗した場合、対応するエラーメッセージが表示されます。
以上が、React Hook FormとZodを用いて複数のフィールドのバリデーションチェックを行う方法になります。これらのライブラリを組み合わせることで、フォームのバリデーションを効率的に行うことが可能となります。ぜひお試しください。