[備忘録]　React Hook formってどう使うの？

## はじめに
この記事は今まで自分の書いた、**githubのTIL**（Today I learnd）をもとにメモ書き程度に書いているためあらかじめご了承ください。（詳しく知りたい方は参考文献に良記事を貼っておきます）

React Hook Form を使えば useState や useRef など煩雑なステート管理を用いずに作成できる。

### 導入きっかけ
今まではFormを作る時は``useState``を用いたり``useRef``を用いたりしていたが、状態管理が必要以上に多くなってしまったりバリデーションがしづらかったりなど、いつも悩みの種だった。そこで巷で話題のReact Hook Formを導入してシンプルかつ堅牢性のあるライブラリーを使用してみようと使ってみることにしました。

### 今までの実装方法
#### useState (状態管理が多すぎる)
このまま入力件数が増えたらその分Stateを足さなくてはならない
```javascript
import React, { useState } from 'react';

const LoginForm = () => {
  const [name, setName] = useState('');
  const [password, setPassword] = useState('');
  const [email, setEmail] = useState('');

  const handleNameChange = (event) => {
    setName(event.target.value);
  };

  const handlePasswordChange = (event) => {
    setPassword(event.target.value);
  };

  const handleEmailChange = (event) => {
    setEmail(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    // フォームの送信ロジックを追加する
    console.log('Submitted:', name, password, email);
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>
          名前:
          <input type="text" value={name} onChange={handleNameChange} />
        </label>
      </div>
      <div>
        <label>
          パスワード:
          <input type="password" value={password} onChange={handlePasswordChange} />
        </label>
      </div>
      <div>
        <label>
          メールアドレス:
          <input type="email" value={email} onChange={handleEmailChange} />
        </label>
      </div>
      <div>
        <button type="submit">送信</button>
      </div>
    </form>
  );
};

export default LoginForm;
```

#### useRef
```javascript
import React, { useRef } from 'react';

const LoginForm = () => {
  const nameRef = useRef('');
  const passwordRef = useRef('');
  const emailRef = useRef('');

  const handleSubmit = (event) => {
    event.preventDefault();

    const name = nameRef.current.value;
    const password = passwordRef.current.value;
    const email = emailRef.current.value;

    // フォームの送信ロジックを追加する
    console.log('Submitted:', name, password, email);

    // 入力フィールドをクリアする
    nameRef.current.value = '';
    passwordRef.current.value = '';
    emailRef.current.value = '';
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>
          名前:
          <input type="text" ref={nameRef} />
        </label>
      </div>
      <div>
        <label>
          パスワード:
          <input type="password" ref={passwordRef} />
        </label>
      </div>
      <div>
        <label>
          メールアドレス:
          <input type="email" ref={emailRef} />
        </label>
      </div>
      <div>
        <button type="submit">送信</button>
      </div>
    </form>
  );
};

export default LoginForm;

````


### React Hook Form導入メリット
1. **state管理などのコードの記述量を減らすことが出来る**
1. **パッケージが軽量**
1. **Unontrolled Componentsのパターンを採用しており、レンダリング回数を減らすことが出来る**

#### メリット1
> React Hook Formは、フォームの状態管理を大幅に簡略化します。通常のReactのuseStateやuseReducerを使用する場合と比較して、より少ないコードでフォームの状態を管理できます。フォームの値やバリデーションエラーなどの状態は、React Hook Formの内部で管理され、開発者が明示的に状態を管理する必要がありません。(ChatGPT回答)
#### メリット2
> React Hook Formは軽量であり、追加の依存関係やパッケージのサイズを最小限に抑えることができます。これにより、パフォーマンスの向上や、フォームのビルドやメンテナンスの容易さが実現されます。また、必要な機能を個別にインポートすることもでき、必要のない機能を含まないことができます。(ChatGPT回答)
#### メリット3
> React Hook Formは、Uncontrolled Componentsのパターンを採用しています。これにより、フォームの入力値の状態をReactの状態として保存する必要がなくなり、フォームコンポーネントの再レンダリング回数が減ります。また、フォームの値の変更が発生しても、それに応じて全体のフォームコンポーネントが再描画されることはありません。これにより、パフォーマンスが向上し、ユーザーエクスペリエンスが改善されます。(ChatGPT回答)


### 実装例
```javascript
import { useForm } from 'react-hook-form';

function App() {
  const { register, handleSubmit } = useForm();

  const onSubmit = (data) => console.log(data);

  return (
    <div className="App">
      <h1>ログイン</h1>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label htmlFor="email">Email</label>
          <input id="email" {...register('email')} />
        </div>
        <div>
          <label htmlFor="password">Password</label>
          <input id="password" {...register('password')} type="password" />
        </div>
        <button type="submit">ログイン</button>
      </form>
    </div>
  );
}

export default App;

```

```javascript
// registerで登録する
<input id="password" {...register("password")} type="password" />
```

```javascript
// validationはターゲットの横に書く
<input
  id="password"
  {...register("password", { required: true })}
  type="password"
/>
```

### Validationライブラリ

ZodとYupっていうValidationライブラリ導入することがスタンダードらしいので導入してみると良い（個人的にはZodの方が好きです）

参考資料

- [REFFECT　React Hook form](https://reffect.co.jp/react/react-hook-form)
- [REFFECT　Zod](https://reffect.co.jp/react/zod-validation)
- [私のTIL](https://github.com/ryota108/Today-I-Learned)