2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

react-hook-form + zod でnullableかつメールアドレスの形式チェックを行う方法

Last updated at Posted at 2024-01-09

はじめに

Webサイトを作っている時、入力していない場合はバリデーションをかけず、一文字でも入力している場合はemailのバリデーションをかけるという流れで少し詰まったので備忘録として書き残しておきます。

問題

emailの入力フォームで

  • 入力は任意(nullでもいい)
  • 入力した場合はemailの形式であるかバリデーション
    という二つを両立させる方法がわからなかった

解決方法

追記です

X(Twitter)でもっといい方法を教えていただきました!

ということで、

z.string().email().optional().or(z.literal(''))

のみで今回タイトルにあるバリデーションは問題なく行えるようです!

そもそも正規表現を自前で書いた理由が、zodの.emailでは日本語の文字を許容してしまうという情報に基づいたものでしたが、バージョン3.22.0にて修正されていたようです🫨
実際に確認せずに古い情報を信じてコードを書くのはダメですね...

バージョン3.22.0以前であれば以下の対応で問題ないかと思われます。

superRefineを使用する。

const registerFormValidation = z
    .object({
        email: z.string().nullable(),
    })
    .superRefine(({ email }, ctx) => {
        if (email !== null && email.length > 0) {

            const regex =
                /^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$/;
            if (!regex.test(email)) {
                ctx.addIssue({
                    path: ["email"],
                    code: "custom",
                    message: "メールアドレスの形式が不正です",
                });
            }
        }
    });

まず、email: z.string().nullable(),で値がnullの時はバリデーションをとおるようにします。
そのあと、superRefineをemailの文字数が1以上の時正規表現を用いてテストします。
正規表現に当てはまらなかった場合、ctx.addIssueを登録してエラーメッセージを生成します。

おわりに

もっといい方法があれば教えてください...!

参考サイト

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?