使用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
相关产品推荐
相关产品推荐

