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

React TSX + react-hook-form + Yup 条件展示表单字段校验实现问题

Yup 多级条件展示字段校验修复方案

原代码存在的问题

  • 语法错误:case 'webmoney 缺失闭合单引号,直接导致代码运行报错
  • 逻辑不符合需求:bank_transfer 分支下直接将 payment_system_A、payment_system_B 对应的所有字段设为必填,没有根据两个复选框的选中状态做条件判断
  • 依赖监听缺失:没有将 payment_system_A、payment_system_B 加入校验依赖,字段选中状态变化时不会触发校验规则更新

修正后的代码实现

const validationSchema = yup.object().shape({
  id: yup.number().required(),
  title: yup.string().required('Required field'),
  is_default: yup.number().oneOf([0, 1]),
  is_confirmed: yup.number().oneOf([1], t('Confirm that the payment details on this form are correct')),
  // 支付系统复选框和id同级,如果是放在method_fields下可移到内层定义
  payment_system_A: yup.boolean(),
  payment_system_B: yup.boolean(),
  method_fields: yup.object().when('id', (id) => {
    const paymentType = paymentMethod[id];
    switch (paymentType) {
      case 'webmoney':
        return yup.object().shape({
          webmoney_account_number: yup.string().required('Required field'),
          webmoney_purpose_of_payment: yup.string().required('Required field'),
          // 第三个webmoney字段按实际需求补充校验规则
        });
      case 'bank_transfer':
        return yup.object().shape({
          // 可在这里定义bank_transfer场景下的公共必填字段
        }).when(['payment_system_A', 'payment_system_B'], ([isASelected, isBSelected]) => {
          const fields = {};
          // 选中payment_system_A时加载对应字段校验
          if (isASelected) {
            Object.assign(fields, {
              payments_name: yup.string().required('Required field'),
              payments_nickname: yup.string().required('Required field'),
              payments_address: yup.string().required('Required field'),
              payments_bank_account_number: yup.string().required('Required field'),
              payments_bank_routing_number: yup.number().required('Required field'),
              payments_bank_name: yup.string().required('Required field')
            });
          }
          // 选中payment_system_B时加载对应字段校验
          if (isBSelected) {
            Object.assign(fields, {
              international_transfers_name: yup.string().required('Required field'),
              international_transfers_address: yup.string().required('Required field'),
              international_transfers_account: yup.string().required('Required field'),
              international_transfers_bank: yup.string().required('Required field'),
              international_transfers_bank_address: yup.string().required('Required field'),
              international_transfers_swifts: yup.string().required('Required field'),
              international_transfers_etc: yup.string().required('Required field')
            });
          }
          return yup.object().shape(fields);
        });
      default:
        return yup.object().shape({});
    }
  })
});

注意事项

  • 若使用 Yup v1 版本,when 回调的第二个参数需要接收 context 对象,从 context 中取 schema 构造返回值,可对应版本官方规则调整写法
  • 如果 payment_system_A、payment_system_B 字段存放在 method_fields 内层对象中,需要将嵌套 when 的依赖参数改为对应内层字段名,不需要跨层级引用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 03:06:09