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

如何在Formik分步表单中配置Yup验证?解决schema报错问题

Formik分步表单Yup验证Schema报错解决

用Formik构建分步表单时,尝试传入Yup Schema数组实现分步验证,出现报错:schema[(intermediate value)(intermediate value)(intermediate value)] is not a function

错误原因

Formik的validationSchema属性仅接受单个Yup对象或返回Yup对象的函数,直接传入数组会导致Formik尝试调用数组(而非函数)进行验证,从而抛出错误。

解决方案

方式一:根据当前步骤动态返回对应Schema

保留原有的Schema数组,将validationSchema改为动态返回当前步骤对应Schema的函数:

  1. 保留原Schema数组定义:
const schema = [
  yup.object().shape({
    field1: yup.string().required("cannot be empty"),
    field2: yup.string().required("cannot be empty"),
  }),
  yup.object().shape({
    field3: yup.string().required("cannot be empty"),
    field4: yup.string().required("cannot be empty"),
  }),
  yup.object().shape({
    field5: yup.string().required("cannot be empty"),
    field6: yup.string().required("cannot be empty"),
  }),
];
  1. 修改Formik组件的validationSchema配置:
<Formik
  initialValues={initialValues}
  // 动态返回当前步骤对应的Schema
  validationSchema={() => schema[currentStep]}
  onSubmit={_handleSubmit}
>
  {({ isSubmitting, dirty, isValid, values, resetForm, validateForm }) => (
    <Form>
      {_renderStepperForm(currentStep)}
      <Button
        size="sm"
        disabled={currentStep === 0}
        onClick={goToPreviousStep}
      >
        Previous
      </Button>
      <Button 
        type="submit" 
        size="sm" 
        onClick={async () => {
          // 手动触发当前步骤验证,通过后再跳转
          const errors = await validateForm();
          if (Object.keys(errors).length === 0) {
            goToNextStep();
          }
        }}
      >
        {currentStep + 1 === stepConstant?.length ? "save" : "Next"}
      </Button>
    </Form>
  )}
</Formik>

关键注意事项

  • currentStep需是Formik组件可访问的状态(比如用useState管理的变量)
  • 建议在跳转下一步前手动调用validateForm(),确保当前步骤所有字段验证通过后再切换步骤,避免跳过验证
  • 若需保留已完成步骤的验证状态(防止用户返回修改后跳过验证),可在切换步骤时重新验证对应步骤

方式二:合并Schema并通过条件控制验证规则(可选)

如果需要确保已完成步骤的字段始终有效,可将所有字段的验证规则合并到一个Schema中,通过yup.when根据当前步骤动态启用验证:

const schema = yup.object().shape({
  field1: yup.string().when('currentStep', {
    is: (step) => step >= 0,
    then: () => yup.string().required("cannot be empty"),
  }),
  field2: yup.string().when('currentStep', {
    is: (step) => step >= 0,
    then: () => yup.string().required("cannot be empty"),
  }),
  field3: yup.string().when('currentStep', {
    is: (step) => step >= 1,
    then: () => yup.string().required("cannot be empty"),
  }),
  // 其他字段同理
});

此时需将currentStep传入Formik的initialValues或通过上下文传递,确保Yup能获取到步骤状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:43:13