如何在Formik+Yup中实现购买日期早于销售日期的验证?
如何用Yup实现datePurchase早于dateSale的验证?
我懂你碰到的问题了——之前尝试用Yup的when()方法实现购买日期早于销售日期的验证却没成功,对吧?别担心,这里有两种靠谱的方式可以搞定这个需求,我给你一步步拆解:
方法一:优化when()结合yup.ref()的用法
你之前可能没正确引用另一个字段的值,其实可以通过yup.ref()来关联datePurchase,并在when()里设置触发条件:
import { Formik, Form } from 'formik'; import * as yup from 'yup'; // 定义验证规则 const validationSchema = yup.object().shape({ datePurchase: yup.date() .min(new Date('01-01-2019'), '购买日期不能早于2019年1月1日') .max(new Date(), '购买日期不能晚于今天') .required('购买日期为必填项'), dateSale: yup.date() .min(new Date('01-01-2019'), '销售日期不能早于2019年1月1日') .max(new Date(), '销售日期不能晚于今天') .required('销售日期为必填项') // 当购买日期有值时,验证销售日期必须晚于它 .when('datePurchase', { is: (purchaseDate) => !!purchaseDate, // 仅当购买日期已填写时触发 then: (schema) => schema.min(yup.ref('datePurchase'), '销售日期必须晚于购买日期') }) }); // 表单组件 const DateForm = () => ( <Formik initialValues={{ datePurchase: '', dateSale: '' }} validationSchema={validationSchema} onSubmit={(values) => console.log(values)} > {({ values, handleChange, handleBlur, errors, touched }) => ( <Form> <div> <label>购买日期:</label> <input name="datePurchase" type="date" onChange={handleChange} onBlur={handleBlur} value={values.datePurchase} /> {errors.datePurchase && touched.datePurchase && ( <span style={{ color: 'red' }}>{errors.datePurchase}</span> )} </div> <div> <label>销售日期:</label> <input name="dateSale" type="date" onChange={handleChange} onBlur={handleBlur} value={values.dateSale} /> {errors.dateSale && touched.dateSale && ( <span style={{ color: 'red' }}>{errors.dateSale}</span> )} </div> <button type="submit">提交</button> </Form> )} </Formik> ); export default DateForm;
关键说明:
yup.ref('datePurchase')会动态引用表单中datePurchase字段的当前值,确保验证规则随用户输入实时更新when()的is条件用来判断是否触发额外验证,避免用户还没填写购买日期就弹出“销售日期必须晚于购买日期”的错误
方法二:自定义验证函数(test()方法)
如果需要更灵活的逻辑,比如处理一些特殊日期格式或者复杂判断,推荐用Yup的test()方法自定义验证规则:
// 在validationSchema的dateSale规则里替换成以下代码 dateSale: yup.date() .min(new Date('01-01-2019'), '销售日期不能早于2019年1月1日') .max(new Date(), '销售日期不能晚于今天') .required('销售日期为必填项') .test( 'is-after-purchase', // 验证规则的唯一标识 '销售日期必须晚于购买日期', // 错误提示信息 function(value) { // 通过this.parent获取整个表单的字段值 const { datePurchase } = this.parent; // 如果购买日期或销售日期为空,跳过这个验证(必填项已经单独验证) if (!datePurchase || !value) return true; // 比较两个日期的大小 return new Date(value) > new Date(datePurchase); } )
关键说明:
this.parent可以访问到表单的所有初始值和当前输入值,方便跨字段验证- 自定义函数返回
true表示验证通过,返回false则触发错误提示
这两种方法都能完美实现你要的“购买日期必须早于销售日期”的验证需求,你可以根据自己的场景选择合适的方式~
内容的提问来源于stack exchange,提问作者plkpiotr
相关产品推荐
相关产品推荐

