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

Yup满足条件后执行自定义校验出现循环依赖问题如何解决

问题解决:Formik+Yup校验邮箱可用性循环依赖错误

错误原因

  • 你触发循环依赖的核心原因是when('email', {...})配置错误:你让email字段的校验规则依赖自身值的变化,逻辑上形成自引用循环,即使添加依赖数组也无法修复该问题
  • 额外的逻辑错误:is: true的判断条件永远不成立,因为email是字符串类型,不可能等于布尔值true,该条件分支永远不会执行,完全达不到你想要的「满足条件再执行异步校验」的需求

正确修改方案

方案1:直接移除错误的when逻辑,在test内部做前置判断

Yup的校验规则按链式调用顺序执行,email()、required()校验不通过时,我们可以直接在自定义test中跳过异步请求逻辑,避免无效的Firebase调用,修改后的完整代码如下:

<Formik
  initialValues={{
    name: '',
    email: '',
    password: '',
    passwordConfirmation: '',
  }}
  validationSchema={Yup.object({
    name: Yup.string()
      .required('Required'),
    email: Yup.string()
      .email('Invalid email address')
      .required('Required')
      .test(
        'checkEmailAvailability',
        'An account with this email already exists',
        async (value) => {
          // 前置判断:格式校验不通过时直接跳过异步请求
          if (!value || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return true
          const auth = getAuth();
          const signInMethods = await fetchSignInMethodsForEmail(
            auth,
            value
          );
          return signInMethods.length === 0;
        }
      ),
    password: Yup.string()
      .min(6, 'Must be at least 6 characters')
      .required('Required'),
    passwordConfirmation: Yup.string().oneOf(
      [Yup.ref('password'), null],
      "Passwords don't match"
    ),
  })}
  onSubmit={(values, { setSubmitting }) => {
  // 你的提交逻辑
  }}
>
{/* 表单渲染内容 */}
</Formik>

方案2:进一步优化请求频率(可选)

如果想要避免用户输入过程中频繁触发Firebase请求,可以配合Formik的校验触发配置使用,仅在邮箱输入框失去焦点时才触发校验:

<Formik
  initialValues={{/* 你的初始值 */}}
  validationSchema={/* 上面修改后的校验Schema */}
  validateOnChange={false} // 关闭输入时实时校验
  validateOnBlur={true} // 仅当输入框失去焦点时触发校验
  onSubmit={/* 你的提交逻辑 */}
>
{/* 表单内容 */}
</Formik>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 08:39:02