React Hook Form + Material UI + yup + TypeScript で良い感じのフォームを作成する

## はじめに
React Hook Form、Material UI、yup を組み合わせたフォームを作成する方法をメモしておきます。

## 始め方シリーズ
良い感じの環境構築についても記事を書いているので、よければこちらもご覧ください。

https://qiita.com/hasehiro0828/items/e021ad5867de285b88b7

https://qiita.com/hasehiro0828/items/ef1736e871b85b039212

https://qiita.com/hasehiro0828/items/9e0606e147d7a5dc3451

https://qiita.com/hasehiro0828/items/70e827c427d965d68e17

https://qiita.com/hasehiro0828/items/6596c8f5eae8030a5d84


## バージョン

```json:package.json
{
  "dependencies": {
    "@hookform/resolvers": "^2.8.3",
    "@mui/material": "^5.1.1",
    "react-hook-form": "^7.20.2",
    "yup": "^0.32.11"
  },
}
```

## コード
```tsx:Form.tsx
import { yupResolver } from "@hookform/resolvers/yup/dist/yup";
import { Button, Checkbox, TextField } from "@mui/material";
import { Controller, useForm } from "react-hook-form";
import * as yup from "yup";

interface FormValues {
  hoge: string;
  num: number;
  checked: boolean;
}

const schema: yup.SchemaOf<FormValues> = yup.object({
  hoge: yup.string().required("必須だよ"),
  num: yup.number().required("必須だよ").min(20, "20以上にしてください"),
  checked: yup.boolean().required("必須だよ").isTrue("チェックしてください"),
});

const Form = (): JSX.Element => {
  const {
    handleSubmit,
    formState: { errors },
    control,
  } = useForm<FormValues>({
    defaultValues: {
      hoge: "",
      num: 1,
      checked: true,
    },
    resolver: yupResolver(schema),
  });

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <Controller
        name="hoge"
        control={control}
        render={({ field }): JSX.Element => (
          <TextField
            {...field}
            type="text"
            label="hoge のラベル"
            multiline
            rows={8}
            variant="filled"
            fullWidth
            error={"hoge" in errors}
            helperText={errors.hoge?.message}
          />
        )}
      />

      <Controller
        name="num"
        control={control}
        render={({ field }): JSX.Element => (
          <TextField
            {...field}
            type="number"
            label="num のラベル"
            variant="filled"
            fullWidth
            error={"num" in errors}
            helperText={errors.num?.message}
          />
        )}
      />

      <Controller
        name="checked"
        control={control}
        render={({ field }): JSX.Element => (
          <Checkbox onChange={(e): void => field.onChange(e.target.checked)} checked={field.value} />
        )}
      />

      <Button type="submit" variant="contained">
        submit
      </Button>
    </form>
  );
};

export default Form;
```

## 参考にさせていただいたサイト
https://react-hook-form.com/get-started#IntegratingwithUIlibraries

- 公式ドキュメント

https://github.com/react-hook-form/react-hook-form/tree/master/examples

- 公式の examples
- 中でも [Controller (MUI, React-Select and etc)](https://codesandbox.io/s/react-hook-form-v7-controller-5h1q5)が参考になります

https://dev.classmethod.jp/articles/mui-v5-rhf-v7/

- こちらは `register` を使う方法
- 公式が `Contoller` を使用していたので、そちらに合わせました。

https://stackoverflow.com/questions/69792558/react-hook-form-build-problem-when-upgrading-nextjs-to-version-12

- yup の import でエラーが出たので、この回答の対応をしました。