🧩

【React】zodでテキスト項目で入力されたinputに対する空文字許容の数値チェック

2024/04/26に公開

概要

テキスト項目で数値を入力するinputがあると思いますが、数値入力で input[type="number"]を使ったら、ユーザから問い合わせが増えてしまった話の記事にもある通りtype="number"のレンダリングがいけてない部分もあるので、そのままテキストで使用するというケースもあるかと思います。
対応としてはチェックの処理で数字以外が入力されたらエラーとするのが考えられますが、zodで数値チェックを行う際に少しハマったので今回メモ書きします。

前提

  • 使用したzodのバージョンは3.23.3です。

ハマったこと

zodでinputの内容を変換するときの対応が3-2. 受け取った値を変換したい (corece / preprocess / transform)の記事にありまして、文字から数値に変換する時はcoerceを使えば問題ないと考えました。ただ、空白を許容する場合はz.coerce.number() defaults empty strings to 0の記事にある通り「0」に変換されてしまいます。こちらの記事には対応策はいくつか紹介されてますが、coerceとは別の手段を考える必要があります。
取り急ぎ今回はpreprocessで、チェック処理を実装したサンプルを以下に記しておきます。

実装サンプル

export const sampleFormSchema = z.object({
  numberText: z.preprocess(
    (v) => {
      const valueStr = String(v);
      if (v != null && valueStr) {
        return parseInt(valueStr);
      }
      return undefined;
    },
    z
      .number({
        invalid_type_error: "数値を入力してください",
      })
      .optional()
  ),
});

Discussion