shimotsu tech

Webフロントエンドエンジニア @ to-R inc.

react-hook-form のフォームに zod でバリデーションを実装する

React 用のフォームバリデーションライブラリ react-hook-form で、zod を使ったバリデーションの実装を行ったのでメモしておきます。

react-hook-form.com

github.com

zod は、型と値を検証できる軽量なバリデーションライブラリで、react-hook-form にはそれ専用のリゾルバが用意されています。

まず、z.object({}) メソッドを用いて、オブジェクトスキーマを作成します。

const schema = z.object({
  title: z.string().nonempty(), // プロパティ `title` は、string型かつ空欄ではない
});

次に、useForm() を呼び出す際に、resolver プロパティを以下のように設定します。(※バリデーション以外の設定も含んでいます)

const {
    register,
    handleSubmit,
    formState: { isValid, isDirty },
  } = useForm<Inputs>({
    resolver: zodResolver(schema), // 上記のスキーマを用いて、リゾルバを設定
    defaultValues: {
      title: '',
    },
    mode: "onChange"
  })

最後に、useForm() で得た値を用いて通常通りフォームを実装します。

const Form: React.FC<props> = ({ onSubmit }) => {
  const {
    register,
    handleSubmit,
    formState: { isValid, isDirty },
  } = useForm<Inputs>({
    resolver: zodResolver(schema),
    defaultValues: {
      title: '',
    },
    mode: "onChange"
  })

  return (
    <form onSubmit={handleSubmit(onSubmit)} className={styles.form}>
      <label>タイトル</label>
      <input
        {...register('title')}
        className={styles.input}
      />
      <div className={styles.buttonWrapper}>
        <CustomButton type="submit" title="登録" disabled={!isDirty || !isValid} />
      </div>
    </form>
  )
}

export default Form

これで、formState 内の isValid の値は zod を介した検証に基づいて返されるようになりました。

この例でいうと、CustomButtondisabled プロパティは、リゾルバによる検証をクリアしているときのみ、 false となります。