💎

Zodのregex()でエラーメッセージを出し分ける

2023/09/27に公開

初めまして。きよそねと申します。UIデザイナー兼フロントエンドエンジニアとして、Webアプリケーションを開発しています。

Zod + React Hook Formでログインフォームのバリデーションを実装する中で、パスワードのスキーマについての発見があったので書き記しておきます。

そもそもZodやReact Hook Formがどういったものなのかについては、以下の記事に分かりやすくまとまっています。

https://zenn.dev/hayato94087/articles/409ce06564122d

TL;DR

  • Zodのregex()は複数連結できる
  • 複数連結することで個別にmessageを指定できる
  • エラーの原因がユーザーに分かりやすくなって嬉しい

詳細

  • 数字・英小文字・英大文字をそれぞれ1文字以上含む
  • 8文字以上

という要件のパスワードのスキーマは、素直に定義すると以下のようになります。

const zodPassword = z
  .string()
  .min(8, { message: "パスワードは8文字以上入力してください" })
  .regex(/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])/, { message: "パスワードは数字・英小文字・英大文字をそれぞれ1文字以上使用してください" })

もちろんこれで十分にバリデーションをかけることができます。しかしユーザーは入力したパスワードが、具体的にどの点において不十分だったのかを知ることができません。

Zodのregex()メソッドは複数連結できます。そのため以下のように定義することで、ユーザーは入力したパスワードのどの点が不十分だったのかを知ることができます。

const zodPassword = z
  .string()
  .min(8, { message: "8文字以上入力してください" })
  .regex(/[0-9]+/, { message: "数字を1文字以上使用してください" })
  .regex(/[a-z]+/, { message: "英小文字を1文字以上使用してください" })
  .regex(/[A-Z]+/, { message: "英大文字を1文字以上使用してください" })

正規表現はあまり可読性が高くないと考えており、条件ごとに分割することで可読性が上がるのも個人的には嬉しいポイントです。

おわりに

ほんのちょっとした工夫ですが、同様の知見がインターネット上でパッと見つけられなかったため記事にしました。同じようにフォームを作成している方の一助になれば幸いです。

また私は現在転職活動を行っています。デザインとフロントエンド双方のスキルを活かせる環境・ポジションがあればぜひお声がけください。

https://twitter.com/kysnrm/status/1705561616912351252

Discussion