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

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后失效,推测是字段层级路径错误导致。


解决方案

核心修改点有两个:

  1. 关联子对象字段时使用完整路径:Yup中引用嵌套字段需要用父对象.子字段的格式,比如contactGroup.phone、contactGroup.email
  2. 修正触发条件的逻辑:原规则用&&要求三个字段同时有值才触发,需要改成||判断任一字段非空

修改后的完整校验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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:10:32