React Hook Formの基本まとめ その2 (zodと組み合わせるパターン)

こんにちは! 今回は前回に引き続き、React Hook Form (RHF) についてまとめます。

zodと組み合わせるパターン

import { useForm } from 'react-hook-form'
import { z }  from 'zod'
import { zodResolver } from '@hookform/resolvers/zod'

const schema = z.object({
  name: z.string().min(1, '名前は必須です'),
  email: z.string().email('正しいメールアドレスを入力してください'),
  age: z.number().min(18, '18歳以上である必要があります')
});

type FormData = z.infer<typeof schema>;

export default function App () {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormData>({
      resolver: zodResolver(schema),
  })

  const onSubmit = (data: FormData) => {
    console.log(data)
  }


  return (
    <form  onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} />
      {errors.name && <p>{errors.name?.message}</p>}
      <input {...register('email')} />
      {errors.email && <p>{errors.email?.message}</p>}
      <input {...register('age', { valueAsNumber: true })  type="number" />
      {errors.age && <p>{errors.age?.message}</p>

      <button type="submit">送信</button>
    </form>
  )
}

解説

zodResolver

  • zodResolverをRHFのuseFormのresolverとして渡すことで、RHFのバリデーションを指定したzodのスキーマに基づいて実行できる

valueAsNumberとtype="number"

  • zodで行うのはバリデーションなので、数値のみ入力させたい場合は、type="number"を指定する
  • type="number"を指定しても、フォームが実際に送信するときは文字列になってしまうので、 RHFのvalueAsNumberを使うと、数値として送信することができる

ポイント

  • zodを使用することで、スキーマをフォームとは別に記述できる
  • そのため、フォームの記述がよりスッキリして可読性が高くなる

おわりに

  • 今回はRHFとzodを組み合わせる方法についてまとめました。次はMUIのようなUIコンポーネントとReact Hook Formを組み合わせるためのControllerパターンについてまとめます。