Antd表单规则中如何校验两个数字输入值的大小关系
Antd 数字区间表单跨字段校验实现
需求说明
- 表单包含两个仅接收数字输入的
InputNumber项,分别对应区间起始值、结束值 - 核心校验规则:起始值必须严格小于结束值,不符合规则时展示antd原生表单错误提示
- 校验逻辑需写入
Form.Item的rules配置中,替代原有提交时手动if判断打印日志的逻辑 - 取值支持两种方案:独立state存储、通过表单实例/ref直接获取字段值
效果参考
- 正常状态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
相关产品推荐
相关产品推荐

