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
相关产品推荐
相关产品推荐

