如何使用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
相关产品推荐
相关产品推荐

