You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hook Form与Zod:必填错误未显示却触发类型错误问题

解决React Hook Form + Zod表单验证中空值触发类型错误而非必填错误的问题

问题原因

当表单中age字段为空时,React Hook Form会将空字符串""传递给Zod进行验证。而Zod的z.number()会优先检查输入类型:空字符串属于string类型,不符合number要求,因此直接触发invalid_type_error,而非required_error——后者仅在字段**完全缺失(值为undefined或未传入)**时才会触发。

解决方案

通过Zod的preprocess方法,先将空字符串转换为undefined,让Zod识别为字段缺失,从而触发必填错误提示;同时支持将合法的数字字符串转换为数字类型,确保验证逻辑符合预期。

最终Schema代码

const Schema = z.object({
  age: z.preprocess(
    (val) => {
      // 空字符串转为undefined,触发必填错误
      if (val === "") return undefined;
      // 将字符串类型的数字转为number,兼容输入场景
      return typeof val === "string" ? Number(val) : val;
    },
    z.number({
      required_error: "Required",
      invalid_type_error: "Invalid type",
    })
  ),
});

type SchemaType = z.infer<typeof Schema>;

const form = useForm<SchemaType>({
  resolver: zodResolver(Schema),
  // 可选:设置默认值为undefined,更贴合必填校验逻辑
  defaultValues: {
    age: undefined,
  },
});

验证效果

  • 当age字段为空时:空字符串被转为undefined,Zod触发required_error,显示"Required"提示。
  • 当输入非数字字符串(如"abc"):转换后得到NaN,Zod识别为无效数字类型,触发invalid_type_error,显示"Invalid type"提示。
  • 当输入数字(如20)或数字字符串(如"20"):正常转换为数字类型,验证通过,且Schema.parse({ age: 20 })能无错误执行。

补充说明

如果你的输入框使用type="number",React Hook Form会自动将输入值转为数字类型(空值时为""),上述方案依然适用。若希望严格限制输入为数字类型,也可以在注册字段时添加type="number",进一步优化用户输入体验。

内容的提问来源于stack exchange,提问作者datnm.qti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:42:50