Yup校验问题:子对象字段关联时lastName必填规则失效求助
问题:Formik+Yup表单校验中关联子对象字段触发必填规则失效
现有联系人表单结构如下:
const contactForm = { title: undefined, firstName: '', lastName: props.contact?.name, contactGroup: { phone: props.contact?.phone || '', email: props.contact?.email || '', }, };
需求:当firstName、contactGroup.phone、contactGroup.email任一字段填写内容时,lastName触发必填校验错误。
原校验规则在仅关联firstName时有效,但加入子对象中的phone和email后失效,推测是字段层级路径错误导致。
解决方案
核心修改点有两个:
- 关联子对象字段时使用完整路径:Yup中引用嵌套字段需要用
父对象.子字段的格式,比如contactGroup.phone、contactGroup.email - 修正触发条件的逻辑:原规则用
&&要求三个字段同时有值才触发,需要改成||判断任一字段非空
修改后的完整校验schema如下:
const schema = yup .object() .shape({ firstName: yup.string().max(256, 'max-length'), lastName: yup.string().when(['firstName', 'contactGroup.phone', 'contactGroup.email'], { is: (firstName, phone, email) => { // 判断任一字段非空(去除首尾空格后不为空字符串) return firstName.trim() !== '' || phone.trim() !== '' || email.trim() !== ''; }, then: yup.string().required('empty').max(256, 'max-length'), }), contactGroup: yup.object().shape( { phone: yup.string().when('email', { is: (email) => !email?.trim() || email === '', then: yup.string().max(256, 'max-length'), }), email: yup .string() .nullable(true) .when('phone', { is: (phone) => !phone?.trim() || phone === '', then: yup.string().email('invalid').max(256, 'max-length'), }), }, [ ['phone', 'email'], ['email', 'phone'], ] ), }) .required();
关键说明:
when数组中传递完整的字段路径contactGroup.phone和contactGroup.email,确保Yup能正确读取嵌套字段的值- 触发条件中增加
trim()判断,避免用户输入空格被误判为已填写 - 将逻辑运算符从
&&改为||,满足任一字段填写即触发必填的需求
内容的提问来源于stack exchange,提问作者Greg-A
相关产品推荐
相关产品推荐

