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

如何用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数组验证逻辑,更易维护:

  1. 调整Schema配置:
const schema = yup.object({
  lotes: yup.array().of(
    yup.object({
      lote: yup.string().required('Lote不能为空'),
      qnt: yup.string().required('Quantidade不能为空')
    })
  ).required('至少需要填写一个批量项')
});
  1. 初始化表单默认值:
const defaultValues = {
  lotes: quantidadeDeLotes.map(() => ({ lote: '', qnt: '' }))
};
  1. 更新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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:15:28