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

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(),
      }),
    })
  ),
});

关键改动说明

  1. 明确依赖路径:用数组形式['mode_of_payment_id.id']指定依赖字段,确保Yup能正确定位到同级的mode_of_payment_id.id。
  2. 函数式Schema扩展:在when的回调中接收当前字段的Schema并扩展,避免创建独立实例,保证条件验证逻辑正确绑定到目标字段。
  3. 对象级可选验证:给account_id对象添加条件必填规则,确保当mode_of_payment_id.id存在时,整个account_id对象不能为null/undefined,同时内部字段满足必填要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:14:56