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

React+Formik+Yup:动态数组为空/未定义时跳过验证

解决方案

问题分析

你的数组包含3个未定义的空元素和1个有效对象,当前Yup会对数组中所有元素(包括空元素)执行校验,导致空元素触发必填项报错。需要实现仅对已定义且非空的元素执行校验,空元素直接跳过。

实现代码

使用Yup.lazy()动态生成校验规则,根据数组元素的实际值决定是否启用校验:

translator_services: Yup.array().of(
  Yup.lazy(item => {
    // 若元素未定义或为空对象,返回无校验规则的schema
    if (!item || Object.keys(item).length === 0) {
      return Yup.mixed();
    }
    // 若元素为有效对象,应用原有的字段校验规则
    return Yup.object().shape({
      translator_category_id: Yup.string().required("Required"),
      translator_category_description: Yup.string().nullable().required("Description is required."),
      translator_category_type_id: Yup.array().nullable().min(1, "Select at least one service type"),
    });
  })
),

原理说明

  • Yup.lazy()会遍历数组的每个元素,根据元素的实际值动态返回对应的校验schema
  • 当元素是undefined(即数组中的empty项)或空对象时,返回Yup.mixed(),这个类型的schema不会执行任何校验逻辑,直接跳过
  • 当元素是有效对象时,返回你原来定义的对象校验规则,正常校验字段的必填性和格式

另一种实现方式(基于条件校验)

如果不想用lazy,也可以给每个字段添加when条件,判断当前元素是否存在后再启用校验:

translator_services: Yup.array().of(
  Yup.object().shape({
    translator_category_id: Yup.string().when("$self", {
      is: (obj) => obj && Object.keys(obj).length > 0,
      then: (schema) => schema.required("Required"),
      otherwise: (schema) => schema.optional()
    }),
    translator_category_description: Yup.string().nullable().when("$self", {
      is: (obj) => obj && Object.keys(obj).length > 0,
      then: (schema) => schema.required("Description is required."),
      otherwise: (schema) => schema.optional()
    }),
    translator_category_type_id: Yup.array().nullable().when("$self", {
      is: (obj) => obj && Object.keys(obj).length > 0,
      then: (schema) => schema.min(1, "Select at least one service type"),
      otherwise: (schema) => schema.optional()
    })
  })
),

这种方式通过$self引用当前元素对象,仅当对象存在且非空时,才启用字段的校验规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:41:05