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

如何基于Formik-Yup实现依赖数组字段值的条件验证?

Yup数组字段条件校验实现方案

问题描述

现有如下Yup校验Schema:

let validationSchema = Yup.object({
modules: Yup.array(
      Yup.object({
        title: Yup.string()
          .required("A module title is required")
          .min(1, "A module title is required"),
        lessons: Yup.array(
          Yup.object({
            lessonTitle: Yup.string().required("A lesson title is required"),
            lessonType: Yup.array()
              .min(1, "Lesson type is required")
              .required("Lesson type is required"),
          })
        ),
      })
    )
      .min(1, "You must add at least one module")
      .required("You must add at least one module"),
})

需要实现两个条件校验但未成功:

  • 若lessonType数组包含"video",则需校验videoFile是否已上传视频,否则在该字段下显示错误信息;
  • 若lessonType数组包含"document",则需校验documentFile是否已上传文件,否则在该字段下显示错误信息。

尝试过Yup.array().when()方法但未成功,不清楚如何对数组字段应用条件校验。对应的数据结构示例:

modules [
  {
    title: "module title", 
    lessons:[
      {lessonTitle:"video title", lessonType:["video"]}, 
      {lessonTitle:"document title", lessonType:["document"]}
    ]
  }
]

解决方案

核心是通过Yup.when()监听lessonType数组,自定义判断逻辑触发对应字段的必填校验。修改后的完整校验Schema如下:

let validationSchema = Yup.object({
  modules: Yup.array(
    Yup.object({
      title: Yup.string()
        .required("A module title is required")
        .min(1, "A module title is required"),
      lessons: Yup.array(
        Yup.object({
          lessonTitle: Yup.string().required("A lesson title is required"),
          lessonType: Yup.array()
            .min(1, "Lesson type is required")
            .required("Lesson type is required"),
          // 视频文件条件校验
          videoFile: Yup.mixed().when('lessonType', {
            is: (types) => types?.includes('video'),
            then: (schema) => schema.required("Please upload a video file"),
            otherwise: (schema) => schema.notRequired()
          }),
          // 文档文件条件校验
          documentFile: Yup.mixed().when('lessonType', {
            is: (types) => types?.includes('document'),
            then: (schema) => schema.required("Please upload a document file"),
            otherwise: (schema) => schema.notRequired()
          })
        })
      )
    })
  )
  .min(1, "You must add at least one module")
  .required("You must add at least one module"),
})

关键说明

  1. 监听数组字段:when('lessonType')指定监听当前对象下的lessonType数组字段
  2. 数组包含判断:is回调接收lessonType的值,通过types?.includes('video')判断数组是否包含目标类型(可选链?.避免数组为undefined时报错)
  3. 文件类型适配:用Yup.mixed()作为字段类型,适配文件上传返回的File对象(若用string会导致校验失败)
  4. 条件分支处理:then分支设置字段为必填,otherwise分支取消必填,确保仅当对应类型被选中时才校验文件上传

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:12:10