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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:53:59