1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React Hook Formを使ってフォームを実装してみる

Last updated at Posted at 2024-07-14

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フックからメソッドを呼び出します。
最低限必要なメソッドは、registerhandleSubmitです。

  • 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, おまけ

最後に必須項目が入力されていないと送信ボタンが押せないように、必須項目が未入力の場合は送信ボタンを「無効」に設定します。
formStateisValidを設定します。

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-formresolver プロパティを介して zod のバリデーションが自動的に適用されるため、<input> 要素の登録時に追加のバリデーションロジックを書く必要がなくなります。

<input id='name' type="text"
  {...register('name')}
/>

参考記事

https://qiita.com/hinako_n/items/06f536d2d130712cc76c
https://qiita.com/Nozomuts/items/60d15d97eeef71993f06

まとめ

Zodを使ったバリデーション設定にはもっと高度なものがあるようですが、一旦今の自分に必要ないかなと思ったので、このくらいにしておきます(ただめんどくさくなっただけです)。
また必要になる機会や、実際の業務で使用した場合は記載していこうと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?