动态添加网格字段的Yup验证Schema设计方案咨询
动态网格字段的Yup验证方案问题与解决
场景说明
我有如下JSON模型,可视为支持动态增删行的网格(可新增或移除gridItems中的行):
{ "sections": [{ "id": "my-section-1", "gridItems": [{ "fields": [{ "id": "field1", "value": "Row 1 Col 1" }, { "id": "field2", "value": "Row 1 Col 2" }] }, { "fields": [{ "id": "field1", "value": "Row 2 Col 1" }, { "id": "field2", "value": "Row 2 Col 2" }] }] }] }
我通过React Hook Form将该JSON映射到UI字段。为保证字段注册唯一性及设置defaultValues,运行时会给字段ID追加-index后缀,实际解析后的字段ID为:
field1-0, field2-0, field1-1, field2-1
现在我需要为这些字段定义/映射Yup验证Schema,正在思考最优方案。所有行中的field1需遵循相同验证规则,field2同理。我的疑问是:
- 是否可以通过模式匹配(如针对
field1-X)来定义Yup验证? - 是否需要使用Yup.array?但问题在于我并非直接从上述结构渲染字段,而是将其复制到带
-index后缀的本地状态变量对象中再渲染UI字段。
问题解答
1. 模式匹配实现统一验证规则
Yup本身没有内置字段名模式匹配的API,但可以通过动态构建Schema实现需求。核心逻辑是遍历本地状态中的所有字段,根据字段ID的前缀(field1-/field2-)绑定对应的验证规则:
import * as yup from 'yup'; // 定义通用验证规则 const field1Validation = yup.string() .required('field1为必填项') .min(2, '长度不能少于2个字符'); const field2Validation = yup.string() .email('请输入有效的邮箱地址') .required('field2为必填项'); // 根据本地状态生成验证Schema const generateValidationSchema = (localFormState) => { const schemaShape = {}; Object.keys(localFormState).forEach(fieldId => { if (fieldId.startsWith('field1-')) { schemaShape[fieldId] = field1Validation; } else if (fieldId.startsWith('field2-')) { schemaShape[fieldId] = field2Validation; } }); return yup.object().shape(schemaShape); }; // 使用示例:传入当前本地状态生成Schema const validationSchema = generateValidationSchema(yourLocalFormData);
这种方式能自动匹配所有带指定前缀的字段,批量应用统一规则,完美适配你的字段命名逻辑。
2. 是否需要使用Yup.array?
不需要。因为你已经将原始的数组结构转换为扁平的键值对对象(字段ID带索引后缀),直接用yup.object()配合动态生成的shape即可满足需求,完全没必要强行使用yup.array()。
如果硬套yup.array(),还需要把扁平结构重新转回数组格式,反而增加不必要的复杂度,和你当前的状态管理方式相悖。
内容的提问来源于stack exchange,提问作者copenndthagen
相关产品推荐
相关产品推荐

