React+Yup+Formik中基于其他字段设置必填项的问题
Yup条件验证:填写mode_of_payment时account_id必填
需求:mode_of_payment_id为非必填字段,但当它的id有值时,account_id的id和name必须设为必填项。当前代码未实现该逻辑。
原代码:
import { array, boolean, object, string } from 'yup'; const validationSchema = object().shape({ remarks: string().nullable(''), remittance_items: array().of( object().shape({ id: string().nullable(), mode_of_payment_id: object().shape({ id: string().nullable(), name: string().nullable(), with_bank_details: boolean(), }), account_id: object().shape({ id: string().when('mode_of_payment_id.id', { is: (id) => !!id, then: string().required('Select an account'), otherwise: string().nullable(), }), name: string().when('mode_of_payment_id.id', { is: (id) => !!id, then: string().required(''), otherwise: string().nullable(), }), }), }) ), });
问题分析
原代码中when的写法存在上下文绑定问题:直接调用string().required()会创建独立的新Schema实例,而非基于当前字段扩展,导致条件验证逻辑未正确生效。同时,依赖字段的路径需要更明确的指向。
修正后的代码
import { array, boolean, object, string } from 'yup'; const validationSchema = object().shape({ remarks: string().nullable(''), remittance_items: array().of( object().shape({ id: string().nullable(), mode_of_payment_id: object().shape({ id: string().nullable(), name: string().nullable(), with_bank_details: boolean(), }), account_id: object().shape({ id: string().when(['mode_of_payment_id.id'], { is: (modeId) => !!modeId, then: (schema) => schema.required('Select an account'), otherwise: (schema) => schema.nullable(), }), name: string().when(['mode_of_payment_id.id'], { is: (modeId) => !!modeId, then: (schema) => schema.required('Account name is required'), otherwise: (schema) => schema.nullable(), }), }).when(['mode_of_payment_id.id'], { // 可选:确保mode有值时,account_id对象本身不能为空 is: (modeId) => !!modeId, then: (schema) => schema.required('Account details are required'), otherwise: (schema) => schema.nullable(), }), }) ), });
关键改动说明
- 明确依赖路径:用数组形式
['mode_of_payment_id.id']指定依赖字段,确保Yup能正确定位到同级的mode_of_payment_id.id。 - 函数式Schema扩展:在
when的回调中接收当前字段的Schema并扩展,避免创建独立实例,保证条件验证逻辑正确绑定到目标字段。 - 对象级可选验证:给
account_id对象添加条件必填规则,确保当mode_of_payment_id.id存在时,整个account_id对象不能为null/undefined,同时内部字段满足必填要求。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

