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

如何使用Yup正确校验分步表单?跨步骤字段访问异常求助

Yup分步表单校验:正确跨步骤访问字段值的方案

问题核心

在嵌套的分步表单Schema中,使用when进行条件校验时,直接引用step1.origin返回undefined,无法跨层级访问父级字段值;同时你当前依赖全局变量的实现方式存在状态污染风险,不符合Schema的纯净性要求。

规范实现方法

1. 定义纯净的顶层Schema

无需全局变量,直接在when中指定完整的字段路径,同时保留Select2值的转换逻辑:

const schema = Yup.object().shape({
  step1: Yup.object().shape({
    origin: Yup.string()
      .transform((value, originalValue) => {
        // 处理Select2返回的对象格式值
        if (originalValue && originalValue.value) {
          return originalValue.value;
        }
        return value;
      })
      .required('Required...')
  }),
  step2: Yup.object().shape({
    code: Yup.string().when('step1.origin', {
      is: 'XX',
      then: (schema) => schema.required('Required...'),
      otherwise: (schema) => schema.nullable()
    })
  })
});

2. 校验时传入完整的表单数据

Yup的when条件依赖整个表单对象的上下文,所以无论全量校验还是分步校验,都需要确保传入包含已完成步骤数据的完整对象:

  • 全量校验(提交时):
const fullFormData = {
  step1: { origin: 'XX' },
  step2: { code: '123' }
};

schema.validate(fullFormData)
  .then(validData => console.log('校验通过:', validData))
  .catch(err => console.log('校验失败:', err.errors));
  • 分步校验(单步骤验证):
    如果只需要校验当前步骤,需合并已完成步骤的数据后,使用validateAt指定校验路径:
// 已完成的step1数据
const savedStep1 = { origin: 'XX' };
// 当前step2的输入数据
const currentStep2 = { code: '' };

// 合并数据并校验step2
schema.validateAt('step2', { step1: savedStep1, step2: currentStep2 })
  .then(() => console.log('step2校验通过'))
  .catch(err => console.log('step2校验失败:', err.errors));

为什么之前的方法会失效?

你之前的代码中when('step1.origin')返回undefined,大概率是因为校验时仅传入了step2的单独数据,而非包含step1的完整对象,导致Yup无法找到对应路径的字段值。全局变量的方式虽然能临时解决问题,但会导致Schema失去纯净性,多表单实例场景下容易出现数据污染。

内容的提问来源于stack exchange,提问作者Yasser Jiménez Martínez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:55:28