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

Formik表单中Yup设默认值后required验证失效问题

Formik + Yup:设置default()后required()验证失效的解决方案

问题原因

Yup的required()验证逻辑是检查字段值是否为undefined、null或空字符串(字符串类型)。你在Yup schema中通过default()给字段设置了非空的默认值(@、0555),当用validationSchema.cast()生成Formik的initialValues时,这些默认值会被填充为字段的初始值——由于它们是有效值,required()会判定字段已填写,自然不会触发必填验证。

解决方案

不要依赖Yup的default()来设置表单初始显示值,而是将初始值和验证规则分离,通过自定义验证来确保用户必须修改默认值:

方法1:使用test()自定义验证规则

// 定义表单初始值(业务要求的默认显示值)
const initialValues = {
  name: "@",
  phone: 0555
};

// 定义验证规则:既检查必填,又排除默认值
const validationSchema = Yup.object().shape({
  name: Yup.string()
    .test(
      "not-default-value",
      "姓名为必填项,请输入真实姓名",
      (value) => value !== "@"
    )
    .required("姓名为必填项"),
  phone: Yup.number()
    .integer()
    .positive()
    .min(1)
    .test(
      "not-default-value",
      "手机号为必填项,请输入真实手机号",
      (value) => value !== 0555
    )
    .required("手机号为必填项"),
});

// Formik组件配置
<Formik 
  initialValues={initialValues} 
  validationSchema={validationSchema}
>
  {/* 你的表单输入组件 */}
</Formik>

方法2:使用notOneOf()排除默认值

如果只需要检查字段值不等于默认值,可以用更简洁的notOneOf()替代自定义test():

const validationSchema = Yup.object().shape({
  name: Yup.string()
    .notOneOf(["@"], "姓名为必填项,请输入真实姓名")
    .required("姓名为必填项"),
  phone: Yup.number()
    .integer()
    .positive()
    .min(1)
    .notOneOf([0555], "手机号为必填项,请输入真实手机号")
    .required("手机号为必填项"),
});

关键说明

  • Formik的initialValues负责表单的初始显示状态,Yup的validationSchema专注于验证逻辑,两者职责分离更清晰。
  • 上述方案既满足了业务对默认显示值的要求,又确保了必填验证能正确触发——当用户未修改默认值时,会提示输入真实内容;当用户清空字段为null/undefined时,required()也会触发验证。

内容的提问来源于stack exchange,提问作者Maram Alsalem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:08:27