実務で、React Hook FormとYupを使ったバリデーション付きフォームを実装したので、
備忘録として残したいと思います。
まず、React Hook FormとはReactでフォームを簡単に扱うことができるライブラリです。
(詳細は割愛いたします)
本記事では、React Hook FormとYupを組み合わせて、シンプルなバリデーション付きフォームを作成する方法を記載します。
全体の流れ
-
Yupでバリデーションルールを定義
yup
を使ってフォームの入力値に対するバリデーションを定義 -
React Hook Formでフォームを管理
useForm
フックを使って、フォームの状態やバリデーションエラーを管理 -
YupのスキーマをReact Hook Formに適用
yupResolver
を使って、React Hook FormにYupスキーマを紐付け -
入力項目に
register
を割り当てる
React Hook Formのregister
関数を使って、フォームの各フィールドを紐付け -
handleSubmit
でフォーム送信処理
バリデーションを通過した場合にのみ送信処理を実行
1. Yupでバリデーションルールを定義する
まず、Yupを使ってフォームのバリデーションルールを定義します。
ここでは簡単に名前とメールアドレスを入力するだけのフォームとします。
import * as yup from "yup";
const formSchema = yup
.object({
name: yup.string().required("名前を入力してください"),
email: yup
.string()
.email("有効なメールアドレスを入力してください")
.required("メールアドレスを入力してください"),
})
.required();
export type FormValues = yup.InferType<typeof formSchema>;
このスキーマでは以下をチェックします
-
name
: 空欄ではないこと -
email
: 有効なメールアドレス形式であること、および空欄ではないこと
yup.InferTypeについて
- Yupで定義されたバリデーションスキーマ(
formSchema
)を元にして、TypeScriptの型定義(FormValues
)を生成 - Yupスキーマで定義したフィールド名やデータ型が、TypeScriptの型定義に自動的に反映されるため、スキーマと型定義の間で不整合が起きるリスクを防ぐことができる
2. React Hook Formでフォームを管理する
次に、useForm
を使ってフォームの状態管理とバリデーションを設定します。
import React from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
const formSchema = yup
.object({
name: yup.string().required("名前を入力してください"),
email: yup
.string()
.email("有効なメールアドレスを入力してください")
.required("メールアドレスを入力してください"),
})
.required();
export type FormValues = yup.InferType<typeof formSchema>;
const MyForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormValues>({
resolver: yupResolver(formSchema), // Yupのスキーマを紐付ける
defaultValues: { name: "", email: "" }, // 初期値の設定
});
const onSubmit = (data: FormValues) => {
console.log("フォームデータ:", data);
// dataには、registerで紐付けたフォームフィールド(nameとemail)の入力値が格納される。
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>名前:</label>
<input {...register("name")} />
{errors.name && <p>{errors.name.message}</p>} {/* バリデーションエラーの表示 */}
</div>
<div>
<label>メールアドレス:</label>
<input {...register("email")} />
{errors.email && <p>{errors.email.message}</p>} {/* バリデーションエラーの表示 */}
</div>
<button type="submit">送信</button>
</form>
);
};
export default MyForm;
フォーム
ポイント解説
1. useForm
とは?
useForm
は、React Hook Formが提供するフォーム管理のメインフックです。フォーム全体を管理するための設定や関数、状態を取得できます。
使い方
以下のようにuseForm
を呼び出すことで、フォームの管理に必要な機能をまとめて取得できます。
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormValues>({
resolver: yupResolver(formSchema),
defaultValues: { name: "", email: "" },
});
主な設定オプション
-
resolver
:
バリデーションを外部ライブラリ(Yupなど)に委託するための設定。ここでは、yupResolver
を使い、Yupスキーマに基づいたバリデーションを行っている -
defaultValues
:
各フィールドの初期値を設定。この例ではname
とemail
の初期値を空文字列(""
)にしている
2.register
とは
register
は、各フォームフィールドをReact Hook Formに登録するための関数です。これを使って、フォームの入力値や状態をReact Hook Formで管理できるようにします。
使い方
以下のように、フォーム要素にregister
を適用します:
<input {...register("name")} />
<input {...register("email")} />
ここで渡す引数(例:"name"
)は、フォームデータ内のフィールド名を指定します。これにより、React Hook Formがそのフィールドを認識し、管理対象とします。
機能
- 入力値の監視と取得:ユーザーが入力した値をリアルタイムで管理
- バリデーションの紐付け:
resolver
で設定したスキーマに基づいて入力値を検証する
3. handleSubmit
とは?
handleSubmit
は、フォームの送信時にバリデーションを実行し、成功時に指定した関数(onSubmit
)を呼び出すための関数です。
使い方
フォームのonSubmit
イベントに以下のように設定します:
<form onSubmit={handleSubmit(onSubmit)}>
動作の流れ
-
フォームが送信される:ボタンを押すことで、
onSubmit
イベントが発火 -
バリデーションの実行:
resolver
で指定したYupスキーマに基づいて入力値が検証される -
成功時(バリデーション通過時):
-
onSubmit
関数が実行され、検証済みの入力データ(data
)が引数として渡される
-
-
失敗時(バリデーションエラー発生時):
- エラー情報が
formState.errors
に格納される
- エラー情報が
const onSubmit = (data: FormValues) => {
console.log("フォームデータ:", data);
// registerで紐付けたフォームフィールド(nameとemail)の入力値が格納される。
// 実際にはAPIの処理などが入る。
};
4. formState.errors
とは?
formState.errors
は、バリデーションエラーの状態を管理するオブジェクトです。
各フィールドごとにエラー情報を格納し、ユーザーにエラー内容を表示する際に利用します。
使い方
{errors.name && <p>{errors.name.message}</p>}
-
errors.name
:name
フィールドに対するエラー情報を持っている -
errors.name.message
: エラーメッセージ(Yupスキーマで指定した文言)が格納されている
コード全体の流れ
-
フォームの管理を
useForm
でセットアップ-
useForm
でフォームの初期値やバリデーションを設定 - 各フィールドを
register
で登録
-
-
フォーム送信時に
handleSubmit
でバリデーション実行- バリデーションを通過した場合、
onSubmit
関数が呼び出される - エラーがある場合は、
formState.errors
にエラー情報が格納される
- バリデーションを通過した場合、
-
エラーがあればユーザーに表示
- 各フィールドごとに
errors
をチェックし、エラーメッセージを表示
- 各フィールドごとに
※完成したフォーム