React Hook Formとは
React Hook Formは、Reactで簡単にフォームを作成・管理できるライブラリです。
従来のフォームライブラリと異なり、Reactのフックを利用しているため、フォームの状態管理やバリデーションを、シンプルなコードで管理することができます。
今回は、React Hook Formを使いバリデーションを設定した簡単なフォームを作成します。
各ファイルを確認したい方はこちらから
実装方法
1, ライブラリのインストール
まずは、React Hook Formを利用するために、以下のコマンドを実行し、ライブラリをインストールします。
npm install react-hook-form
2, フォームの型宣言
フォームで扱うデータの型を定義します。TypeScriptを利用することで、型安全な開発を実現できます。
interface FormData {
name: string;
email: string;
gender: 'male' | 'female';
memo: string;
country: string;
agreeToTerms: boolean;
}
3, useFormの宣言
useForm
フックからメソッドを呼び出します。
最低限必要なメソッドは、register
とhandleSubmit
です。
-
register
: 各フォームフィールドに対する登録関数。これにより、フォームフィールドがReact Hook Formによって管理されるようになります -
handleSubmit
: フォームが送信されたときに呼び出される関数。これをフォームのonSubmit
イベントハンドラとして使用します
今回はエラーメッセージを設定したいので、formState
も記述しています。
const { register, handleSubmit, formState: { errors } } = useForm();
useFormのオプション引数
useForm
フックには、デフォルト値やバリデーションルールなどを設定するためのオプション引数を設定することができます。
-
mode
: バリデーションが実行されるタイミングを設定します-
onSubmit
:送信イベントでトリガーされる -
onBlur
:フォームからフォーカスが離れたときにトリガーされる -
onTouched
:フォームからフォーカスが離れたときにトリガーされる -
onChange
:入力の度にトリガーされる
-
-
defaultValues
: 入力のデフォルト値を設定します
const defaultValues: FormData = {
name: '山田太郎',
email: 'admin@example.com',
gender: 'male',
memo: '',
country: '',
agreeToTerms: false
};
const { register, handleSubmit, formState: { errors } } = useForm({
defaultValues,
mode: 'onChange'
});
4, registerを使ってFormを管理する
register
関数を使用して、フォーム要素とReact Hook Formを紐付けます。
フォーム要素のタグ内にregister関数を使った記述をすることで、その要素をReact Hook Formで管理できるようになります。
- 第1引数:参照の名前を登録する(必須)
- 第2引数:バリデーションのルールをオブジェクト形式で設定します
<input id='name' type="text"
{...register('name', {
required: '名前は必須入力です。', // 必須入力
maxLength: { // バリデーション設定
value: 20, // 最大文字数
message: '名前は20文字以内にしてください。' // エラーメッセージ
}
})}
/>
5, エラーメッセージを設定する
errors
オブジェクトを使用して、各フォーム要素に対するエラーメッセージを表示します。
<div className='errorMessage'>{errors.name?.message}</div>
6, handleSubmitでフォームを送信する
handleSubmit
関数を使用して、フォーム送信時の処理を定義します。
今回は、送信時コンソールに送信内容を表示します。
const onSubmit = (data: FormData) => {
console.log(data);
};
7, おまけ
最後に必須項目が入力されていないと送信ボタンが押せないように、必須項目が未入力の場合は送信ボタンを「無効」に設定します。
formState
にisValid
を設定します。
const { register, handleSubmit, formState: { errors, isValid } } = useForm({
defaultValues,
mode: 'onChange'
});
isValidがfalseの時は送信ボタンを無効とします。
<button type='submit' className='submitButton' disabled={!isValid}>送信</button>
Zodを使ったバリデーション設定
React Hook Formでは、ライブラリを使用することで、より高度で複雑なバリデーションを設定することができます。
今回は、Zodを使って、前述と同じバリデーションを実装してみます。
Zodはtypescriptの型システムを活用して、フォームの入力値などアプリケーションで扱うデータが、宣言したスキーマに沿っているかを検証することができます。
1, Zodのインストール
npm install zod
2, Zodによるスキーマ定義
Zodを使用して、フォームデータのスキーマを定義します。型安全なバリデーションを実現するために、各フィールドの型、必須項目、値の範囲などを厳密に定義します。
const schema = z.object({
name: z.string().nonempty('名前は必須入力です。').max(20, '名前は20文字以内にしてください。'),
email: z.string().nonempty('メールアドレスは必須入力です。').email('メールアドレスの形式が不正です。'),
gender: z.enum(['male', 'female']),
memo: z.string().min(10, '備考は10文字以上にしてください。'),
country: z.string().nonempty('国は必須選択です。'),
agreeToTerms: z.boolean().refine(val => val, '利用規約に同意してください。')
});
3, React Hook Formの初期化
resolver
プロパティ、zodResolver
を使って zod
スキーマを react-hook-form
に統合しています。これにより、フォームのバリデーションが zod
のスキーマに基づいて行われます。
const { register, handleSubmit, formState: { errors, isValid } } =
useForm<FormData>({
resolver: zodResolver(schema),
defaultValues,
mode: 'onChange'
});
4, フォーム要素の管理
zod
を使用してバリデーションスキーマを設定した場合、react-hook-form
の resolver
プロパティを介して zod
のバリデーションが自動的に適用されるため、<input>
要素の登録時に追加のバリデーションロジックを書く必要がなくなります。
<input id='name' type="text"
{...register('name')}
/>
参考記事
https://qiita.com/hinako_n/items/06f536d2d130712cc76c
https://qiita.com/Nozomuts/items/60d15d97eeef71993f06
まとめ
Zodを使ったバリデーション設定にはもっと高度なものがあるようですが、一旦今の自分に必要ないかなと思ったので、このくらいにしておきます(ただめんどくさくなっただけです)。
また必要になる機会や、実際の業務で使用した場合は記載していこうと思います。