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

Formik+Yup校验Schema在MUI多步骤Dialog中异常求助

解决Formik多步骤表单全局触发校验的问题

问题根源

你直接将Yup Schema数组传给Formik的validationSchema属性,但Formik不支持数组类型的校验规则。它无法识别按步骤拆分的Schema,会默认对所有字段执行校验,导致当前步骤未输入的字段全部触发错误提示。

解决方案

1. 动态返回当前步骤的Schema

将validationSchema改为函数形式,根据当前步骤currentStep返回对应的Yup Schema,让Formik只校验当前步骤的字段。

2. 控制校验时机(可选)

如果不需要实时校验输入框,可关闭validateOnChange和validateOnBlur,只在点击「Next/Submit」时执行校验,避免输入过程中触发无关错误。

修正后的代码

Formik组件修改

<Formik
  innerRef={formikFormRef}
  enableReinitialize
  initialValues={businessTypeInitialState}
  // 动态返回当前步骤的校验Schema
  validationSchema={() => businessContactsSchema[currentStep]}
  // 可选:关闭实时校验,仅提交时校验
  validateOnChange={false}
  validateOnBlur={false}
  onSubmit={(values, { resetForm }) => {
    // 原有提交逻辑保持不变
    if (isLastStep) {
      let payload = {
        ...values,
        record_type_id: contactRecordType === 'Corporate' ? '1' : '2',
        contact_id: props.openDialog?.data?.contactId,
        same_address: isSameAddress,
        billingAddressId: props.openDialog?.data?.billingAddress.addressId,
        contactAddressId: props.openDialog?.data?.contactAddress.addressId,
      };
      if (props.openDialog?.dialogType === 'addContact') {
        addContactMutation(payload, {
          onSuccess: (data) => {
            if (data.statusCode === 200) {
              queryClient.invalidateQueries('contacts');
              setContactData(data);
              setCurrentStep(5);
              resetForm();
            } else if (data.statusCode === 403)
              setAPIResponse({ message: data.message, code: data.statusCode });
            else setAPIResponse({ message: 'There was a server error', code: data.statusCode });
          },
        });
      } else if (props.openDialog?.dialogType === 'editContact') {
        updateContactMutation(payload, {
          onSuccess: (data) => {
            if (data.statusCode === 200) {
              queryClient.invalidateQueries('contactDetails');
              setCurrentStep(0);
              props.onClose();
            }
          },
        });
      }
    } else {
      if (isSameAddress && currentStep === 2) return setCurrentStep(currentStep + 2);
      return setCurrentStep(currentStep + 1);
    }
  }}
>
  {/* 原有渲染逻辑保持不变 */}
</Formik>

自定义实时校验(可选)

如果需要保留实时校验,但仅校验当前步骤字段,可替换validationSchema为自定义validate函数:

validate={(values) => {
  const errors = {};
  const currentSchema = businessContactsSchema[currentStep];
  try {
    // 校验当前步骤字段,abortEarly设为false收集所有错误
    currentSchema.validateSync(values, { abortEarly: false });
  } catch (err) {
    err.inner.forEach((e) => {
      errors[e.path] = e.message;
    });
  }
  return errors;
}}

额外说明

  • 确保enableReinitialize为true,切换步骤时Formik会重新计算校验规则
  • Yup Schema数组businessContactsSchema无需修改,保持原有结构即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:47:01