React Hook Form onBlur模式下验证不触发问题求助
问题描述
我开发了一个根据蛋白质、碳水化合物和脂肪三个输入值自动计算卡路里的表单,希望在onBlur事件触发时验证输入为正整数,但验证功能未生效,formState.errors对象始终为空。我已尝试在useForm中设置mode: onBlur,但没有效果。此外,因诸多原因我未使用input type="number"(不使用数字类型输入的原因参考GOV.UK设计系统团队的结论:他们出于多种考量更改了数字输入的类型)。
解决方案
1. 适配文本输入的验证规则调整
由于使用type="text"输入,用户输入值为字符串类型,直接用数字类型验证规则会失效。需自定义校验逻辑,先将字符串转为数字,再校验是否为正整数。以Yup为例,修改验证schema:
import * as yup from "yup"; import { yupResolver } from "@hookform/resolvers/yup"; const calorieSchema = yup.object().shape({ protein: yup .string() .required("请输入蛋白质含量") .test( "positive-integer-check", "请输入有效的正整数", (val) => { const num = Number(val); return !isNaN(num) && Number.isInteger(num) && num > 0; } ), carbs: yup .string() .required("请输入碳水化合物含量") .test( "positive-integer-check", "请输入有效的正整数", (val) => { const num = Number(val); return !isNaN(num) && Number.isInteger(num) && num > 0; } ), fat: yup .string() .required("请输入脂肪含量") .test( "positive-integer-check", "请输入有效的正整数", (val) => { const num = Number(val); return !isNaN(num) && Number.isInteger(num) && num > 0; } ), });
2. 正确配置useForm
确保useForm传入mode: "onBlur"和正确的resolver:
const { register, handleSubmit, formState: { errors } } = useForm({ mode: "onBlur", resolver: yupResolver(calorieSchema), });
3. 正确绑定输入框
每个输入框需通过register注册,并展示错误信息:
<div> <label>蛋白质:</label> <input type="text" {...register("protein")} /> {errors.protein && <span style={{ color: "red" }}>{errors.protein.message}</span>} </div>
4. 可选:限制输入仅为数字
为避免用户输入无效字符,可添加输入过滤逻辑:
const filterNonNumeric = (e) => { e.target.value = e.target.value.replace(/[^0-9]/g, ""); }; // 绑定到输入框的onChange <input type="text" {...register("protein")} onChange={filterNonNumeric} />
失效原因说明
原验证失效是因为文本输入的数值为字符串类型,默认数字验证规则无法识别字符串格式的数字,导致校验逻辑未触发,formState.errors始终为空。通过自定义test规则先转换类型再校验,就能解决这个问题。
内容的提问来源于stack exchange,提问作者Marc Fletcher
相关产品推荐
相关产品推荐

