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

使用React Hook Form与Zod校验数字输入时提示非数字的问题

问题解决:React Hook Form + Zod 数字输入框始终触发“必须为数字”错误

核心原因

HTML的type="number"输入框,实际返回的value是字符串类型,而你用的z.number()校验规则期望接收数字类型。React Hook Form默认不会自动做类型转换,所以哪怕你输入的是数字,传给Zod的仍是字符串,直接触发invalid_type_error。

两种解决方法

方法1:在Controller中添加setValueAs做类型转换

修改你的Controller组件,通过setValueAs把输入的字符串转成数字:

<Controller
  name="calories"
  control={control}
  defaultValue={1}
  setValueAs={(value) => parseInt(value, 10)} // 新增:将字符串转为整数
  render={({ field }) => (
    <input
      {...field}
      type="number"
      className="w-full px-3 py-2 border rounded-md"
    />
  )}
/>
  • 如果需要支持小数,把parseInt换成parseFloat即可;
  • 若输入为空,可额外处理(比如value ? parseInt(value, 10) : 0),避免出现NaN。

方法2:用Zod的coerce.number()自动转换类型

修改Zod校验规则,用z.coerce.number()替代z.number(),它会自动尝试把输入值转为数字:

calories: z
  .coerce.number({
    required_error: "Calories is required",
    invalid_type_error: "Calories must be a number",
  })
  .int()
  .positive()
  .min(1, { message: "Calories should be at least 1" }),
  • 该方式会处理字符串数字、空字符串等场景:空字符串会被转为NaN,触发必填错误;非数字内容转换失败则触发“必须为数字”错误,符合预期逻辑。

内容的提问来源于stack exchange,提问作者Aušrys Mikoliūnas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:47:28