てらブログ

てらブログ

日々の学習の備忘録

React Hook Form × Zod × TypeScriptでフォームを作成する②

背景

前回の残課題だった下記について、作業を進めてみたのでまとめてみる。
・制御コンポーネント・非制御コンポーネントでのReact Hook Formの使い方の違いについて
・Zodで少し複雑なバリデーションを作成する

制御コンポーネント・非制御コンポーネントでのReact Hook Formの使い方の違いについて

そもそも制御・非制御コンポーネントとは

制御・非制御コンポーネントについて、一言でいうと下記のとおり。
制御コンポーネントはライブラリ(React)が「入力要素の状態」を管理
非制御コンポーネントは「入力要素の状態」を DOM 自身が保持
参照:
フォーム – React
非制御コンポーネント – React

制御コンポーネントではControllerを使用する

ControllerだらけになってしまうとReact Hook Formの良さが半減する気が...
参照:
Controller

Chakra UI

単純にChakura UI = 制御コンポーネント、かと思いきやそうでもないみたい。
Chakra UIのドキュメントでもregisterで紹介されてたりする。
参照:
Chakra UI + React Hook Form - Chakra UI

Zodで少し複雑なバリデーションを作成する

シンプルなバリデーションだとschemaは下記のような感じ。

const schema = z.object({
  fruit: z.string().nonempty({ message: "未入力です" }),
});

例えば下記のように、既に登録したデータの重複チェックをしたいとする。

.refine()メソッドで、カスタムバリデーションロジックを実現する。

const fruits = ["りんご", "ばなな", "どらごんふるーつ"]

const schema = z.object({
  fruit: z
      .string()
      .nonempty({ message: "未入力です" })
      .refine(value => !fruits.includes(value), {
        message: "既に存在しています",
      }),
});

参照:
Zod | Documentation