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

如何让Yup仅在满足前置条件后执行第二个matches校验?

问题:Yup条件触发邮箱格式校验

需求:仅当输入字符串中至少包含一个@且其后紧跟.时,才执行邮箱格式的matches()校验;否则不触发格式校验。当前代码中test()方法会抵消后续matches()的作用,尝试when方法时出现循环依赖错误。

当前错误代码示例

方式一:test方法抵消matches校验

const regex =
  /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

export const emailSchema = yup.object().shape({
  email: yup
    .string()
    .test('dontCheckUntil', '', (_, context: AnyObject) => {
      return /@.\./.test(context.originalValue)
    })
    .matches(regex, { message: 'Invalid Email' }),
})

方式二:when方法触发循环依赖

export const emailSchema = yup.object().shape({
  email: yup
    .string()
    .when('email', {
      is: (val: string) => {
        console.log('val = ', val)
        return true
      },
      then: (schema) => {
        console.log('schema = ', schema)
        return schema
      },
    })
    .matches(regex, { message: 'Invalid Email' }),
})

解决方案

方案一:在test方法中整合条件判断与格式校验

直接用test替代matches,在方法内部先判断前置条件,满足时再校验邮箱格式,不满足则直接通过校验:

const regex =
  /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

export const emailSchema = yup.object().shape({
  email: yup.string().test('email-validation', 'Invalid Email', (value) => {
    // 空值或不满足@后紧跟.的条件,直接通过校验
    if (!value || !/@\./.test(value)) {
      return true;
    }
    // 满足前置条件时,执行邮箱格式校验
    return regex.test(value);
  }),
});

方案二:正确使用when方法避免循环依赖

采用when的函数式写法,直接获取当前字段值,避开循环依赖问题:

const regex =
  /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

export const emailSchema = yup.object().shape({
  email: yup.string().when(
    (value) => value,
    {
      is: (val) => val && /@\./.test(val),
      then: (schema) => schema.matches(regex, 'Invalid Email'),
      otherwise: (schema) => schema,
    }
  ),
});

说明

  • 方案一逻辑集中,代码简洁,适合简单场景;
  • 方案二通过函数式写法规避循环依赖,适合需要拆分校验逻辑的场景;
  • 两种方案都会随onChange触发,但仅当输入满足@后紧跟.的条件时,才会执行邮箱格式校验,否则直接通过。

内容的提问来源于stack exchange,提问作者me-me

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:00:59