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

React-Datepicker搭配Formik+Yup首次失焦仅required校验生效问题

问题根因

该现象本质是两个逻辑不匹配:

  • React-Datepicker的默认事件触发逻辑不会在首次选值时同步触发Formik的字段触摸标记更新
  • Formik默认仅展示**已标记为touched(已触摸)**字段的校验错误,首次操作时只有必填校验因为值为空触发,非必填的规则虽然校验了但因为字段没标记为touched,错误不会展示,不是校验没生效。

解决方案

第一步:补充导入触摸状态更新方法

从useFormikContext中新增解构setFieldTouched方法:

const { setFieldValue, validateField, handleBlur, setFieldTouched } = useFormikContext();

第二步:修改值变更逻辑,同步标记触摸状态

修改onChange回调,值更新后立即标记字段为已触摸,再主动触发校验:

onChange={val => {
  setFieldValue(field.name, val);
  // 第三个参数为false表示标记触摸时不自动触发校验,后续主动调用更可控
  setFieldTouched(field.name, true, false);
  validateField(field.name);
}}

第三步:修复失焦和日历关闭事件的逻辑

React-Datepicker的onBlur事件返回的target不一定携带正确的字段名,需要手动指定,同时优化日历关闭的校验逻辑:

onBlur={() => {
  // 手动构造Formik handleBlur需要的事件对象,指定字段名
  handleBlur({ target: { name: field.name } });
}}
onCalendarClose={() => {
  // 关闭日历时如果已经选值,直接标记触摸+触发校验
  setFieldTouched(field.name, true, true);
}}

可选:修复Yup日期校验的时间偏差问题

当前写的min(new Date())取的是Schema初始化时的时间,如果打开表单后停留到第二天再校验,会出现日期判断错误,改成函数形式动态取当前时间:

startDate: yup.date().nullable().required('Start Date is required')
  .min(() => new Date(), 'Start Date must be later than today'),

调整后首次选择日期就能触发全量校验,错误信息会正常展示。

内容的提问来源于stack exchange,提问作者gene b.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 16:15:03