如何用Yup动态验证两个数字输入的大小关系?
解决方案:修复Yup交叉验证后错误提示不动态更新的问题
问题原因
React Hook Form 默认仅验证当前被修改的字段。当你修改number1时,number2的验证规则依赖number1,但number2未被修改,所以不会重新执行验证,导致旧的错误提示残留。
解决方法
通过监听字段变化,手动触发依赖字段的验证,确保双向验证规则动态生效。
步骤1:配置React Hook Form与Yup Schema
首先用yup.object().shape()正确包裹验证规则(原代码缺少这一层,会导致Schema不完整):
import { useForm } from "react-hook-form"; import * as yup from "yup"; const { register, handleSubmit, formState: { errors }, watch, trigger } = useForm({ validationSchema: yup.object().shape({ number1: yup .number() .required("number1为必填项") .when("number2", (number2, schema) => { return number2 ? schema.max(number2, "number1必须小于等于number2") : schema; }), number2: yup .number() .required("number2为必填项") .when("number1", (number1, schema) => { return number1 ? schema.min(number1, "number2必须大于等于number1") : schema; }), }), mode: "onChange", // 开启输入时实时验证 });
步骤2:监听字段变化并触发依赖验证
使用watch监听number1和number2的变化,一旦其中一个改变,自动触发另一个字段的验证:
import { useEffect } from "react"; const number1 = watch("number1"); const number2 = watch("number2"); useEffect(() => { // 当number1变化时,验证number2 if (number1 !== undefined) { trigger("number2"); } }, [number1, trigger]); useEffect(() => { // 当number2变化时,验证number1 if (number2 !== undefined) { trigger("number1"); } }, [number2, trigger]);
步骤3:渲染输入框与错误提示
按常规方式渲染输入框和错误信息:
<form onSubmit={handleSubmit((data) => console.log(data))}> <div> <label>number1:</label> <input type="number" {...register("number1")} /> {errors.number1 && <p>{errors.number1.message}</p>} </div> <div> <label>number2:</label> <input type="number" {...register("number2")} /> {errors.number2 && <p>{errors.number2.message}</p>} </div> <button type="submit">提交</button> </form>
替代方案:使用Yup的test方法(更灵活)
如果when方法的触发逻辑不够直观,可以用test方法自定义验证规则,效果一致:
validationSchema: yup.object().shape({ number1: yup .number() .required("number1为必填项") .test("max-number2", "number1必须小于等于number2", function(value) { const { number2 } = this.parent; return value <= number2; }), number2: yup .number() .required("number2为必填项") .test("min-number1", "number2必须大于等于number1", function(value) { const { number1 } = this.parent; return value >= number1; }), }),
同样需要配合上述的watch和trigger逻辑来触发依赖字段的验证。
内容的提问来源于stack exchange,提问作者Süleyman Furkan Binay
相关产品推荐
相关产品推荐

