Yup使用when方法对数组内对象做条件必填校验问题
问题原因
你的条件校验不生效核心有两个问题:
when方法默认只会在当前字段所在的同级对象上下文里查找匹配字段,你写的isAgeRequired是和people数组平级的根级字段,和嵌套在数组项里的age字段差了两层上下文,默认路径根本匹配不到对应的值- 原schema没有显式声明根级的
isAgeRequired字段规则,Yup校验时不会正确把该字段纳入跨层级访问的上下文里
修正方案
两种写法都可以实现需求,选一种即可:
写法1:相对路径引用(简洁直观)
Yup的when支持相对路径写法,用..表示向上一级上下文查找,从数组项的person对象到根对象需要向上找两层,所以路径写../../isAgeRequired即可,同时补全根字段的类型定义:
import { object, array, string, number, boolean } from 'yup'; const validator = object({ people: array( object({ name: string().required(), age: number() .nullable() .when("../../isAgeRequired", { is: true, // 条件命中时要求age必填,自动排除null/undefined空值 then: (schema) => schema.required(), // 条件不命中时保持可空 otherwise: (schema) => schema.nullable() }) }) ), // 补全根级字段定义 isAgeRequired: boolean().required() });
写法2:上下文判断(兼容性更好,不用记路径)
如果怕相对路径写错,可以直接在when里通过校验上下文拿到根级值判断,适配所有Yup版本:
import { object, array, string, number, boolean } from 'yup'; const validator = object({ people: array( object({ name: string().required(), age: number() .nullable() .when({ // 直接从上下文栈取最外层根对象的isAgeRequired值判断 is: (_, context) => { const rootContext = context.from[context.from.length - 1].value; return rootContext.isAgeRequired === true; }, then: (schema) => schema.required(), otherwise: (schema) => schema.nullable() }) }) ), isAgeRequired: boolean().required() });
校验效果验证
- 当
isAgeRequired: false时,age为null可以正常通过校验 - 当
isAgeRequired: true时,people数组里所有age为null/undefined的项都会触发必填校验报错
内容的提问来源于stack exchange,提问作者Jacobdo
相关产品推荐
相关产品推荐

