如何用Yup验证动态生成的`lope${index}`/`qnt${index}`表单字段?
如何用Yup验证动态生成的必填表单字段
问题分析
你当前的表单字段通过quantidadeDeLotes数组动态生成,字段名格式为lope${index}和qnt${index},无法提前在Yup Schema中枚举所有字段,常规固定字段验证方式不适用。
解决方案一:动态构建Yup Schema
根据quantidadeDeLotes的长度,动态生成对应字段的验证规则:
// 在组件内部生成Schema,依赖quantidadeDeLotes const schema = yup.object().shape( quantidadeDeLotes.reduce((validationRules, _, index) => { validationRules[`lope${index}`] = yup.string().required('Lote不能为空'); validationRules[`qnt${index}`] = yup.string().required('Quantidade不能为空'); return validationRules; }, {}) ); // 配合useForm使用 const { control, formState: { errors }, handleSubmit, setValue, getValues, clearErrors, } = useForm({ resolver: yupResolver(schema), });
如果quantidadeDeLotes长度会动态变化(用户添加/删除字段),用useMemo确保Schema随数组更新:
const schema = useMemo(() => { return yup.object().shape( quantidadeDeLotes.reduce((acc, _, index) => { acc[`lope${index}`] = yup.string().required('Lote不能为空'); acc[`qnt${index}`] = yup.string().required('Quantidade不能为空'); return acc; }, {}) ); }, [quantidadeDeLotes]);
解决方案二:重构表单数据结构(更推荐)
将扁平动态字段改为数组对象形式,适配Yup数组验证逻辑,更易维护:
- 调整Schema配置:
const schema = yup.object({ lotes: yup.array().of( yup.object({ lote: yup.string().required('Lote不能为空'), qnt: yup.string().required('Quantidade不能为空') }) ).required('至少需要填写一个批量项') });
- 初始化表单默认值:
const defaultValues = { lotes: quantidadeDeLotes.map(() => ({ lote: '', qnt: '' })) };
- 更新useForm与渲染逻辑:
const { control, formState: { errors }, handleSubmit, setValue, getValues, clearErrors, } = useForm({ resolver: yupResolver(schema), defaultValues }); // 渲染时使用数组路径作为字段名 {quantidadeDeLotes.map((_, index) => ( <View style={{ flexDirection: 'row', marginTop: spacing.s }} key={index}> <TextInput control={control} type={'default'} name={`lotes[${index}].lote`} placeholder="Lote" viewStyle={{ flex: 0.7 }} error={errors.lotes?.[index]?.lote} /> <View style={{ width: 20 }}></View> <TextInput control={control} type={'default'} name={`lotes[${index}].qnt`} placeholder="Quantidade" viewStyle={{ flex: 0.3 }} mask={MASKS.CRM} keyboardType={Platform.OS === 'android' ? 'numeric' : 'number-pad'} error={errors.lotes?.[index]?.qnt} /> </View> ))}
为什么正则写法无效
Yup的object()方法不支持用正则表达式作为字段名匹配动态字段,因此这种写法无法生效,必须通过动态构建Schema或重构数据结构解决。
内容的提问来源于stack exchange,提问作者Nilton Schumacher F
相关产品推荐
相关产品推荐

