使用react-hook-form与Yup构建动态表单时的验证问题
解决React Hook Form + Yup动态表单的验证问题
问题原因分析
- 数组长度验证不动态更新:Yup的数组
min规则默认不会在数组元素增减时自动触发重新验证,且React Hook Form默认模式下仅在提交时验证,导致添加足够选项后错误提示仍存在。 - 第一个选项未触发验证:未正确配置表单验证模式,且输入变化时未触发对应字段的验证逻辑,导致第一个选项的非空规则仅在提交时生效。
具体解决方案
1. 修正Yup验证Schema
确保数组长度校验和每个元素的非空校验规则明确:
import * as Yup from "yup"; const formSchema = Yup.object().shape({ options: Yup.array() .min(2, "至少需要2个选项") .of( Yup.string() .trim() .required("选项不能为空") ) .required("选项列表不能为空") });
2. 配置React Hook Form验证模式
开启onChange模式,让输入变化时自动触发验证:
const { register, handleSubmit, trigger, formState: { errors } } = useForm({ resolver: yupResolver(formSchema), mode: "onChange" });
3. 动态操作时触发验证
在添加、删除选项以及输入内容变化时,手动触发对应字段的验证:
- 添加选项函数:
const addOption = () => { setOptions(prev => [...prev, ""]); trigger("options"); // 触发数组整体验证 };
- 删除选项函数:
const removeOption = (index) => { setOptions(prev => prev.filter((_, i) => i !== index)); trigger("options"); // 触发数组整体验证 };
- 输入框绑定逻辑:
{options.map((option, index) => ( <div key={index}> <input {...register(`options.${index}`)} value={option} onChange={(e) => { const newOptions = [...options]; newOptions[index] = e.target.value; setOptions(newOptions); // 触发当前选项的验证 trigger(`options.${index}`); // 触发数组整体验证,确保长度规则生效 trigger("options"); }} placeholder={`选项 ${index + 1}`} /> {errors?.options?.[index] && ( <p className="error">{errors.options[index].message}</p> )} </div> ))}
效果说明
修改后:
- 当选项数量少于2个时,实时显示“至少需要2个选项”的错误提示,数量达标后自动消失;
- 每个选项输入为空时,实时显示“选项不能为空”的提示,输入内容后自动消失;
- 提交时的验证逻辑保持原有正常效果。
内容的提问来源于stack exchange,提问作者Anmol Kansal
相关产品推荐
相关产品推荐

