React Hook Formのアップデート内容 - Version 7 

(❤️ ブログ記事を翻訳してくれた日本のチーム、[Kotaro](https://twitter.com/kotarella1110)、[Keiya](https://twitter.com/_keiya01)、[Marina](https://twitter.com/marin_a___)に感謝します。)

React Hook Formもそろそろ2年目を迎えようとしています。プロジェクト自体は、初日と同じように今でも活発に活動しています。この数年の間に、バージョン7の作成やデザインに繋がる多くの学びや経験がありました。私はここで、次のメジャーバージョンでの改善点とその理由をいくつか紹介します。フォームを構築するという点で、React開発者がより楽に開発できるようにする私たちの使命に変わりはありません。

## V7 visions:

￼
📖 (DX)厳密に型付けされたフォーム
🏋🏻‍♀️ シンプルさと一貫性
🏎 パフォーマンス
💁‍♂️ パッケージサイズの削減

---------

このビジョンを説明するために、APIの変更点を見ていきましょう。

### </> register

主な変更点の一つは `register` API です。ほとんどの開発者が知っているように、React Hook Form は `TypeScript` を使って構築されており、ほとんどの `TypeScript` 開発者にとって、型安全性があることは重要な側面です。私たちが直面していた課題の一つに、input `name` を型チェックすることがありましたが、 TypeScript 4.1のアップデート[Template Literal Types](Typeshttps://www.typescriptlang.org/docs/handbook/2/template-literal-types.html)で可能になりました。このアップデートには本当に興奮して、React Hook Formで使えるようにすぐに取り掛かり始めました。

nameを型安全にするには以下のように変更する必要があります。

```diff_jsx
- <input name="test" ref={register} />;
+ <input {...register("test")} />;

// 以下のpropsがinputに分散されます。
const { onChange, onBlur, ref, name } = register("test");
```

このように、register 関数を呼び出すことで型チェックができるようになりました。元のAPIには賛否両論ありますし、型安全性と相性が悪いのは間違いありません。この変更によって、 `useController`, `Controller` などのAPIでも型チェックも行ってくれるようになります。

次の画像は、入れ子になったフィールドの入力名に対する型チェックの様子を示しています。

![Screen Shot 2021-02-14 at 11.53.34 am](https://dev-to-uploads.s3.amazonaws.com/i/vbnrnt2ivgj019aacpb2.png)

β版をインストールした状態で、以下のコードサンドボックスで試すことができます。

https://codesandbox.io/s/react-hook-form-register-ts-ip2j3?from-embed

### </> resolver

スキーマを使ってバリデーションしている開発者のために、`resolver`がパワーアップしています。`resolver`はバリデーションの状況が不足していました。つまり、どのinputsがバリデーションされたかの情報を取得することができていませんでした。私たちはこの部分を改善しており、開発者はどのフィールドが検証されたかにアクセスできるようになり、その`ref`も同様に行うことができるようになります。これにより、以下のような機能が利用できるようになります。

- **バリデーションの最適化**: スキーマバリデーションライブラリがフィールドレベルのバリデーションをサポートしている場合、開発者は `onChange` の度にスキーマ全体を実行せずにバリデーションを最適化することができます。

- **フォーカス管理**: より良いカスタムフォーカス管理のための、input DOM 要素へのアクセス。

以下に `Resolver` の型定義を示します:

```diff_tsx
- resolver: (values: any, context?: object) => Promise<ResolverResult> | ResolverResult
+ resolver: (
+   values: any, 
+   context: object | undefined, 
+   options: { 
+     criteriaMode?: 'firstError' | 'all', 
+     names?: string[],
+     fields: { [name]: field } // Support nested field
+   }
+ ) => Promise<ResolverResult> | ResolverResult 
```

[Joris](https://twitter.com/_jorisre) はこれらの素晴らしい仕事の裏側にいる人です。今後、`resolver` について詳しい技術記事を書いてくれるでしょう。

### </> useFormState

現在のフックフォームのバージョンでは、フォームの状態の更新は `useForm` を呼び出したルート/フォームレベルで再レンダリングされます。バージョン7ではこれが変更され、新たに導入されたカスタムフック `useFormState` を使うと、コンポーネントレベルで個々のフォーム状態の更新を監視できるようになります。これによって、フォームの状態の更新がコンポーネントに通知されるタイミングを開発者側でコントロールできるようになります。また、`useController` と `Controler` の中に `useFormState` を組み込んでいるので、制御された各inputは再レンダリングの観点から完全に分離されます。

```ts
// Subscribe to isDirty, touchedFields at the component level
const { isDirty, touchedFields } = useFormState();

// Subscribe **only** to isDirty and isTouched.
const Test = () => {
  const { meta: { isDirty, isTouched } } = useController();
}
```

ここでは、この新しいカスタムフックを利用して、再レンダリングがコンポーネントレベルで分離されている`DevTool`の良い例を紹介します。

![Screen Recording 2021-02-14 at 12.39.28 pm](https://dev-to-uploads.s3.amazonaws.com/i/c6f4l5q2b6uzrt9jsk6y.gif)

### </> useForm

初期バージョンの当初から、HTMLの標準とネイティブフォームの挙動に合わせたものにしようとしています。その例として、inputが削除されるとその入力値も削除されます。しかし、このような動作は、多くのReact開発者に、なぜアンマウント後に入力値が消えてしまうのかということに戸惑いを与えていました。その戸惑いを解消するために、`shouldUnregister`という設定を用意して、入力値が消えないようにするかユーザー側で選択できるようにしていました。その結果、コード内に多くの余分なロジックと複雑さをもたらすことになっていました。バージョン7では `shouldUnregister` を廃止し、開発者は `unregister` で入力値の削除を制御しなければならなくなります。この変更には賛否両論ありますが、ほとんどのReact開発者にとっては、この変更はより意味のあるものになると思います。以下に例を示します。

```ts
const [show, setShow] = React.useState(true);

// V6 the following input value will be removed
{show && <input ref={register} name="test"} 

// V7 the following input value will be retained
{show && <input {...register('test')}} // V7

// V7 until the following line is invoked then the value will be removed
unregister('test')
```

また、この変更はライブラリのバンドルサイズの変更にも大いに役立ちました。

![Screen Shot 2021-02-14 at 11.32.26 am](https://dev-to-uploads.s3.amazonaws.com/i/2cjrp4ic36sgpfkt6oca.png)

---------

## 結論

React Hook Form は、一般的にはより良い型チェックを持つようになり、より小さく、より速く、より開発者に優しいものになります。この投稿で、私たちがバージョン 7 に盛り込もうとしている改善点とその根拠を理解していただけると幸いです。もし何かフィードバック、懸念、質問があれば、いつでも私たちの [バージョン 7 RFC](https://github.com/react-hook-form/react-hook-form/discussions/3714…) に参加してください。

V7についてYouTubeに投稿したこちらの[short talk](https://youtube.com/watch?v=ZBfBiwyR2HY…)も見ることができます(17分)。

## おまけに

また、以下のような改善を行いました。

**Documentation**:

![Screen Shot 2021-02-14 at 11.45.16 am](https://dev-to-uploads.s3.amazonaws.com/i/vcdkmc0tlju0iih57eaj.png)

**DevTool**:
![localhost_3000_(iPad)](https://dev-to-uploads.s3.amazonaws.com/i/3gyzrpdoqlkjccmfgcu1.png)
 
## Thanks

このメジャーバージョンに関わってくださった皆様、貢献してくださった皆様に感謝します。

- 日本チームの皆さん、ありがとうございました。[Kotaro](https://twitter.com/kotarella1110), [Keiya](https://twitter.com/_keiya01) と日本の開発者コミュニティに感謝します。

- [Joris](https://twitter.com/_jorisre)さんは、`resolver`の次のバージョンを作ってくれた人で、残りの人は[hook form team](https://react-hook-form.com/about-us)さんです。

- V7の議論に一貫して関わり、バグや問題を一人で報告してくれた [wdfinch](https://github.com/wdfinch)。

応援＆協賛ありがとうございます:heart:

![Screen Shot 2021-02-14 at 12.06.48 pm](https://dev-to-uploads.s3.amazonaws.com/i/qbl23z34z3lbremrlwqi.png)