React Hook Formを初めて使う人へ

開発のプロジェクトで「ReactHookFormで実装して」と言われて触る機会があり,初心者なりに何度か詰まってから理解したので,つまらない用に超絶簡易ドキュメントを書く.

## React Hook Formとは

[Home](https://react-hook-form.com/)

### 特徴

- onChangeを走らせずにすみパフォーマンスがつおい
- inputやselectのvalueをsubmitのときに拾ってくれる

多分他にもっとある

---

## install

npm

```
npm install react-hook-form
```

yarn

```
yarn add react-hook-form
```

---

## 普通に使う

公式から持ってきたサンプルを説明します.

```jsx
import React from "react"
import { useForm } from "react-hook-form"

export default function App() {
  const { register, handleSubmit, watch, errors } = useForm()
  const onSubmit = data => console.log(data)

  console.log(watch("example")); // watch input value by passing the name of it

  return (
    {/* "handleSubmit" will validate your inputs before invoking "onSubmit" */}
    <form onSubmit={handleSubmit(onSubmit)}>
    {/* register your input into the hook by invoking the "register" function */}
      <input name="example" defaultValue="test" ref={register} />
      
      {/* include validation with required or other standard HTML validation rules */}
      <input name="exampleRequired" ref={register({ required: true })} />
      {/* errors will return when field validation fails  */}
      {errors.exampleRequired && <span>This field is required</span>}
      
      <input type="submit" />
    </form>
  );
}
```

### useFormをimportする

`import { useForm } from "react-hook-form"`

### 必要なものを分割代入して使う

`const { register, handleSubmit, watch, errors } = useForm()`

最低限`register`と`handleSubmit`は必要になるかな

### 監視対象にregisterを設定

`<input name="example" defaultValue="test" ref={register} />`

ref属性が`register`がであるものを監視

registerは以下のように引数にオブジェクトを渡すことで,バリデーションの設定ができる

`ref={register({ required: true })}`

その他の詳細設定はここを参照↓

[https://react-hook-form.com/jp/api#register](https://react-hook-form.com/jp/api#register)

### 送信の設定

`<form onSubmit={handleSubmit(onSubmit)}>`

formタグのonSubmit属性に`handleSubmit()`を設定.この引数にフォームを送信する関数を渡す

今回は,`const onSubmit = data => console.log(data)`が実行される

仕組みは,refにregisterが設定された要素のvalueが,その要素のnameがプロパティとなり,dataにオブジェクトとして渡される.

今回であれば,

`data = {example: "入力されたvalue",exampleRequired: "入力されたvalue"}`と言った具合

### バリデーションのエラーメッセージ

registerに関するエラーは,

`const { register, handleSubmit, watch, errors } = useForm()`

で定義した`errors`に返ってくるので

`errors.exampleRequired`とすれば呼び出せる

---

## 外部ライブラリに対応した使い方

さて,便利なHookFormだが,Material-UIなどのツールと共存すると正常に動作しないので困る.

ここをよくわかっていないと,「Material-UIと共存できないとかwww 使う意味なくね？wwww」と言われる.

制御ができない場合はControllerコンポーネントを使って制御する

制御ができない場合とはref属性を設定することができないもののようです.

### Controllerをimportする

```jsx
import { useForm, Controller } from "react-hook-form";
```

もちろんuseFormも忘れずに

### controlを定義しておく

```jsx
const { handleSubmit, register, errors, control } = useForm();
```

こんな感じに,普通に使い場合に加えて,Controllerコンポーネントとcontrolを準備する.

### 外部ライブラリのコンポーネントを制御する書き方

今回のサンプルはみんな大好きMaterialUI

```jsx
<Controller
  name="gender"
  // control属性忘れずに
  control={control}  
  // component
  as={
    <RadioGroup aria-label="gender" name="gender1" >
      <FormControlLabel value="female" control={<Radio />} label="Female" />
      <FormControlLabel value="male" control={<Radio />} label="Male" />
      <FormControlLabel value="other" control={<Radio />} label="Other" />
      <FormControlLabel value="disabled" disabled control={<Radio />} label="(Disabled option)" />
    </RadioGroup>
  // validation
	rules={{ required: true }}
  }
/>
```

オブジェクトのプロパティとなるname属性をセットしましょう

`name="gender"`

先程定義したcontrol属性もこんな感じにセットします 

`control={control}`

そして制御したいコンポーネントをasに入れます.

今回はMaterialUIのラジオボタンです.

また,このControllerコンポーネントを使用した場合はregisterを使わないので,バリデーションどーすんの？となる.この場合はrules属性を使う.ここがドキュメントちゃんと読んでいなかったので詰まった😣

`rules={{ required: true }}`

こんな感じでOK

## 欠点

TypeScriptとの相性がわるい（かもしれない）

試してはないし,よくわかっていない🤤