React Hook Form は、Reactでフォームを扱うためのライブラリです
Contents
フォームの入力内容はuseStateで管理しない
通常フォームの入力内はuseStateで入力内容変更のたびに再レンダリングされて、いつでもアクセス可能な値として管理してます。
↓
React Hook Formは入力時に再レンダリングせず、送信時にrefでDOMから値を取得します
React Hook Formは非制御コンポーネントからどうやって変更を検知しているのか – commmune Engineer Blog
(途中で値を取得したい場合は、そのように記述することも可能)
主要な機能
register、handleSubmit,、formStateこの3つはreact-hook-formで最も基本的で頻繁に使用される機能です。
register
inputやtextareaなどのフォーム要素をreact-hook-formに「登録」して、値の管理とバリデーションを任せる機能
handleSubmit
フォームで下記のように書くとonSubmit()をコールする前にバリデーションをして、OKであれば実行します
<form onSubmit={handleSubmit(onSubmit)}>
onSubmit={…} ← これはHTML属性
onSubmit ← これは自分で定義した関数名
名前が同じで紛らわしいですが、たまたま慣習的に同じ名前を使っているだけです。
handleSubmit(onSubmit)
↓
- フォーム送信イベントをキャッチ
- event.preventDefault() を実行(ページリロード防止)
- 全フィールドのバリデーション実行
- エラーがあれば → onSubmitは呼ばれない
- エラーがなければ → onSubmit(data) を実行
formState
フォームの現在の状態(エラー、送信中、タッチ済みなど)を取得できるオブジェクトです。
よく使うプロパティ
typescript
const {
errors, // バリデーションエラー
isValid, // 全フィールドが有効か
isSubmitting, // 送信処理中か
isDirty, // 初期値から変更されたか
isSubmitted, // 送信が完了したか
touchedFields // フォーカスされたフィールド
} = formState;バリデーション機能
Zodを使用したバリデーション
Zodとはデータのバリデーションと型定義を同時に行えるライブラリ です。
Zodの基本的な使用方法
z.object() でスキーマを作り、parse() でデータを検証します。
エラーがある場合は例外を投げ、正しい場合のみ安全に型付きデータとして返します。
またz.infer で Zodのスキーマ型推論もできます
型推論とは、プログラマが型を明示的に書かなくても、コンパイラが自動的に型を判定してくれる機能
↓エディターでホバーすると型の確認できます(これは型推論ではなく普通に明示的にFCと型指定されてます)

zodResolverでReact hook formとZodを連携
React Hook Form がフォーム送信時に呼び出す「バリデーション処理」を、
Zod のスキーマを使って実行できるようにする関数 です。
React Hook Formのみ(register内でバリデーション定義)
export function RHFOnlyForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
{...register("email", {
required: "メールアドレスは必須です",
pattern: {
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: "有効なメールアドレスを入力してください",
},
})}
/>
{errors.email && <p>{errors.email.message}</p>}
<button type="submit">送信</button>
</form>
);
}React Hook Form + Zod
const schema = z.object({
email: z.string().nonempty("メールアドレスは必須です").email("有効なメールアドレスを入力してください"),
});
export function RHFZodForm() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema),
});
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} />
{errors.email && <p>{errors.email.message}</p>}
<button type="submit">送信</button>
</form>
);
}「Zod」を使用したスキーマの例
https://ics.media/entry/240611