useStateを使っているフォームにreact Hook Formを導入する

## はじめに

useStateで管理しているフォームに`React Hook Form`を導入しました。
useStateのところをどうするかわからなくて調べたのでメモとして残します
### 開発環境
- React Hook Form
- TypeScript
- React
## フォームを作成
まずは下のコードのような形でフォームを作成
このフォームに`React Hook Form`でバリデーションを追加する
```react:From.tsx
import { useState } from "react";

export const Form = () => {
  const [name,setName] =useState<string>("");
  const [email,setEmail] =useState<string>("");
  return(
    <form >
      <p>
        名前：
        <input type="text" value={name} onChange={(e) => setName(e.target.value)}/>
      </p>
      <p>
        メールアドレス
        <input type="text" value={email} onChange={(e) => setEmail(e.target.value)} />
      </p>
      <button type="submit">登録</button>
    </form>
  )
}
```

## react-hook-form を使ったフォーム管理
まずはインストール
```
npm install react-hook-form
```
バリデーションの種類はいくつかあるが
今回は必須とエラーメッセージを実装する

https://www.react-hook-form.com/get-started

コード全体は以下のように書き換える

```react:Form.tsx
import { useForm } from "react-hook-form";

type FormValues = {
  name: string;
  email: string;
};

export const Form = () => {
  const { register, handleSubmit, formState: { errors } } = useForm<FormValues>();

  const onSubmit = (data: FormValues) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <p>
        名前：
        <input type="text" {...register("name", { required: "名前は必須です" })} />
        {errors.name && <span style={{ color: "red" }}>{errors.name.message}</span>}
      </p>
      <p>
        メールアドレス：
        <input type="text" {...register("email", { required: true })} />
        {errors?.email?.type === "required" && <p style={{ color: "red" }}>メールアドレスは必須です</p>}
      </p>
      <button type="submit">登録</button>
    </form>
  );
};
```

## 型定義
typeScriptで作成したので型を定義します。
今回は名前とメールアドレスの２つ
```typescript
type FormValues = {
  name: string;
  email: string;
};
```
## registerとhandleSubmit
useStateは削除する
代わりに`useForm`から`register`と`handleSubmit`を使用

[register](https://www.react-hook-form.com/get-started#Registerfields)は入力された値を参照するために使う
[handleSubmit](https://www.react-hook-form.com/get-started#Handleerrors) は、フォームの送信時にバリデーションを実施する
バリデーション後に実行したい内容を`onSubmit` に記述する
```diff_typescript
export const Form = () => {
-  const [name,setName] =useState<string>("");
-  const [email,setEmail] =useState<string>("");
+  const { register, handleSubmit, formState: { errors } } = useForm<FormValues>();

+  const onSubmit = (data: FormValues) => {
+    console.log(data);
+  };
```

## formの書き換え

```diff_javascript
- <form >
+ <form onSubmit={handleSubmit(onSubmit)}>
      <p>
        名前：
-        <input type="text" value={name} onChange={(e) => setName(e.target.value)}/>
+        <input type="text" {...register("name", { required: "名前は必須です" })} />
+        {errors.name && <span style={{ color: "red" }}>{errors.name.message}</span>}
      </p>
      <p>
        メールアドレス：
-        <input type="text" value={email} onChange={(e) => setEmail(e.target.value)} />
+        <input type="text" {...register("email", { required: true })} />
+        {errors?.email?.type === "required" && <p style={{ color: "red" }}>メールアドレスは必須です</p>}
      </p>
      <button type="submit">登録</button>
</form>
```
- `register("name", { required: "名前は必須です" })` で必須入力を設定し、エラーメッセージを追加
- `register("email", { required: true }) `でも設定することができる
`errors?.email?.type === "required"`でエラーメッセージを表示

## まとめ

- `useState`なしでフォームを管理
- `register` に `required` を設定し、簡単にバリデーションを追加
- `errors` を使ってエラーメッセージを表示
- `handleSubmit` でバリデーションを実施し、データを取得

react-hook-form の導入でuseStateを使うことがなくなり、バリデーションチェックも簡単に行えるようになりました

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてくださ！
▼▼▼

https://projisou.jp