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

Antd表单规则中如何校验两个数字输入值的大小关系

Antd 数字区间表单跨字段校验实现

需求说明

  • 表单包含两个仅接收数字输入的InputNumber项,分别对应区间起始值、结束值
  • 核心校验规则:起始值必须严格小于结束值,不符合规则时展示antd原生表单错误提示
  • 校验逻辑需写入Form.Item的rules配置中,替代原有提交时手动if判断打印日志的逻辑
  • 取值支持两种方案:独立state存储、通过表单实例/ref直接获取字段值

效果参考

  • 正常状态UI:
    表单正常UI
  • 校验错误提示效果:
    校验错误预期效果

原有问题代码

const App = () => {
  const [start, setStart] = useState(1);
  const [end, setEnd] = useState(2);
  const formRef = useRef();

  const handleSubmit = () => {
    if (end < start) {
      console.log("End cannot be lesser than start");
    } else if (end === start) {
      console.log("End cannot be same as start");
    } else {
      console.log("Added :)", start, end);
    }
  };

  return (
    <Form
      onFinish={handleSubmit}
      layout="vertical"
      ref={formRef}
      requiredMark={false}
    >
      <div>
        <Form.Item
          name="formStart"
          rules={[
            {
              required: true,
              message: "Please select a form start"
            }
          ]}
        >
          <InputNumber
            placeholder="Start"
            min={1}
            max={100}
            onChange={(e) => setStart(e)}
          />
        </Form.Item>
        <Form.Item
          name="formEnd"
          rules={[
            {
              required: true,
              message: "Please select a form end"
            }
          ]}
        >
          <InputNumber
            placeholder="End"
            min={1}
            max={100}
            onChange={(e) => setEnd(e)}
          />
        </Form.Item>
        <Form.Item>
          <button htmlType="submit">Submit</button>
        </Form.Item>
      </div>
    </Form>
  );
};

实现方案

直接利用antd Form规则配置中的自定义校验器validator做跨字段取值校验,不需要额外维护独立state存储输入值,校验通过后才会触发onFinish提交逻辑。为了避免修改单侧输入值时对侧校验提示不更新,输入值变化时同时触发两个字段的校验即可。

完整实现代码:

import { Form, InputNumber, Button } from 'antd';
import { useRef } from 'react';

const App = () => {
  const formRef = useRef();

  const handleSubmit = (values) => {
    // 所有校验通过后才会进入该逻辑,可直接使用字段值
    console.log("Added :)", values.formStart, values.formEnd);
  };

  return (
    <Form
      onFinish={handleSubmit}
      layout="vertical"
      ref={formRef}
      requiredMark={false}
      initialValues={{
        formStart: 1,
        formEnd: 2
      }}
    >
      <div>
        <Form.Item
          name="formStart"
          rules={[
            {
              required: true,
              message: "请输入起始值"
            },
            {
              validator: (_, value) => {
                if (value === undefined || value === null) return Promise.resolve();
                const endValue = formRef.current?.getFieldValue('formEnd');
                // 结束值已填写时,校验起始值必须小于结束值
                if (endValue !== undefined && endValue !== null && value >= endValue) {
                  return Promise.reject('起始值必须小于结束值');
                }
                return Promise.resolve();
              }
            }
          ]}
        >
          <InputNumber
            placeholder="Start"
            min={1}
            max={100}
            onChange={() => {
              // 起始值变化时,触发结束值重新校验
              formRef.current?.validateFields(['formEnd']);
            }}
            style={{ width: '100%' }}
          />
        </Form.Item>
        <Form.Item
          name="formEnd"
          rules={[
            {
              required: true,
              message: "请输入结束值"
            },
            {
              validator: (_, value) => {
                if (value === undefined || value === null) return Promise.resolve();
                const startValue = formRef.current?.getFieldValue('formStart');
                // 起始值已填写时,校验结束值必须大于起始值
                if (startValue !== undefined && startValue !== null && value <= startValue) {
                  return Promise.reject('结束值必须大于起始值');
                }
                return Promise.resolve();
              }
            }
          ]}
        >
          <InputNumber
            placeholder="End"
            min={1}
            max={100}
            onChange={() => {
              // 结束值变化时,触发起始值重新校验
              formRef.current?.validateFields(['formStart']);
            }}
            style={{ width: '100%' }}
          />
        </Form.Item>
        <Form.Item>
          <Button type="primary" htmlType="submit" block>Submit</Button>
        </Form.Item>
      </div>
    </Form>
  );
};

关键逻辑说明

  • 自定义校验器通过表单ref实例直接获取关联字段的值,不需要额外维护state同步输入值,减少冗余代码
  • 两个输入框值变化时互相触发关联字段校验,避免出现单侧值修改后,另一侧错误提示残留、不更新的问题
  • 所有校验逻辑由antd Form统一管控,错误提示样式、触发时机和组件原生校验完全一致,不需要手动控制提示显隐
  • 只有所有校验规则全部通过时,才会执行onFinish中的提交逻辑,不需要在提交函数中重复做值判断

内容的提问来源于stack exchange,提问作者Sai Krishnadas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:39:12