【React Hook Form】 基本機能まとめ

# はじめに
React Hook Formを使う機会があったので備忘録としてまとめていきます。間違っているところやアドバイスがあればコメントいただければ嬉しいです。

# 環境
- react v17.0.2
- typescript v4.1.2
- react-hook-form v7.8.4

# 概要
React Hook Formを使用するとバリデーションなどの機能が少ないコード量で簡単に実装することができます。

# 基本的な使い方
```
npx create-react-app react-hook-form-sample --template typescript
```
ライブラリをインストールします。今回はv7.8.4を使用します。


## メソッドの呼び出し
```react
const { register, handleSubmit, errors } = useForm()
```
基本的にはこのように使用したいメソッドを呼び出して使用します。

## registerメソッド
各フォームのregisterメソッドを渡すと、そのフォームが管理対象となります。registerメソッドを渡さないとボタンをsubmitしても送信できないので、送信する各フォームにこのメソッドを渡す必要があります。

v6では下記のようにref属性にregisterを渡していたそうですが、

```react
<form>
  <input
    name='name'
    ref={regster}/>
</form>
```

v7からはregisterメソッドが{ onChange, onBlur, name, ref }を返却するようになったため、スプレッド構文で下記のように記述できるようになりました。引数でそのフォームのキーを渡しています。

```react
<form>
  <input {...register("name")/>
</form>
```

スプレット構文を使わず、省略しないで書くと

```react
<form>
  <input id="name" name={name.name} onChange={name.onChange} ref={ref} onBlur={onBlur} />
</form>
```

のようになります。

## handleSubmitメソッド
handleSubmitメソッドは、「フォームから送信された値のバリデーションを実行する役割」があります。ボタンクリック時にバリデーションが実行されるようにしたいので、formタグのonSubmitにhandleSubmitメソッドを渡します。

```react
<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register("name")/>
</form>
```

handleSubmitの引数に、バリデーション通過後に送信された値を受け取る関数を渡してあげます。このようにコールバック関数を引数に渡すことで、送信した値がバリデーションを通過しないとonSubmitが実行されないようにしてくれます。
これでフォームから送信された値を受け取ることができました。
次はバリデーションを設定していきます。

## バリデーションの設定
バリデーションを設定するには、先程のregisterメソッドの第2引数にバリデーションの設定を渡してあげます。

下記のようにregisterメソッドの第2引数に波括弧で囲ったrequire:trueを渡してあげると必須チェックをしてくれます。

```react
<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register("name", { required: true })/>
</form>
```

各フォームに複数個バリデーションを設定したい時も、波括弧の中でカンマ区切りで複数設定することができます。バリデーションの種類については後述します。

## errorsメソッド
バリデーションを設定することができたので、続いてerrorsメソッドを使用してエラーメッセージを表示していきます。
バリデーション時にエラーが起こると「errors + キー名」にオブジェクトが割り当てられます。そこにエラーメッセージを割り当てることができます。

```react
{errors.name && errors.name.type === "required" && <span>名前を入力してください</span>}
```

上記のように記述するとエラーメッセージを表示する処理が簡単に実装できます。
errosメソッドはバリデーションエラーが発生するとオブジェクトを返し、エラーがなければ「undefined」を返すので上記のように存在チェックをすることができます。typeにはバリデーションの種類が入るので今回は「require」だった場合、trueになるようにチェックしています。
左辺の2つのチェックがtrueの場合、spanタグで囲われたエラーメッセージを表示する動きになっています。

## 処理の流れ
大まかな処理の流れとしては、

送信ボタンをクリック
↓
registerメソッドで登録されたフォームの値の送信
↓
handleSubmitメソッドに値が渡されバリデーションチェックを行う
↓
- バリデーションエラーが発生した場合、errorsメソッドにオブジェクトが渡され、エラーメッセージが表示され、onSubmitは動作しない。
- バリデーションを通過すると、handleSubmitの引数に渡されたコールバック関数が実行される
↓
実行された関数でフォームの値を受け取る

## バリデーションの種類
最後によく使うバリデーションをまとめておきます。

### 必須チェック
入力が必須のフォームに設定する。一番良く使いそう。

```react
<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register("name", { required: true })/>
</form>
```

### 文字数の最大、最小値チェック

最大値を「maxLength」、最小値を「minLength」で設定する。

```react
<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register("name", { minLength: 6 })/>
</form>
```
上記は「6文字以上の入力が必須」という意味になります。

```react
<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register("name", { minLength:6, maxLength:12 })/>
</form>
```
組み合わせて使うこともできます。

### 数値の最大、最小値チェック

数値の最大値、最小値の設定は、「min」と「max」を使用します。

```react
<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register("age", { min:18, max:65 })/>
</form>
```

上記では、「18〜65」の間で入力を制限しています。

## 特定の文字列チェック
特定の文字列を正規表現を使用してチェックすることもできます。
valueに正規表現を設定することで、特定の文字列を設定できます。

```react
<input id="email" label="メールアドレス" type="email" {...register("email", {
          pattern: {
          value: /\S+@\S+\.\S+/,
          message: "メールアドレスの形式が違います" }})}/>
```

## 参考にした記事
・[公式ドキュメント](https://react-hook-form.com/jp/api/)
・[説明をあまり妥協しないreact-hook-formの使い方[基本]](https://shuxblog.com/react-hook-form-usage-base/)
・[React Hook Form v7とMaterial UIを組み合わせるときの挙動](https://dev.classmethod.jp/articles/mui-with-rhf-v7/)



## 最後に
今回は基本的なメソッドだけしか使用してませんが、watchやresetなど便利そうなメソッドがたくさんあるので、今後使っていこうと思います。