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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:43:16