使用React Hook Form与Yup做文件输入校验时value为undefined如何解决
问题原因及解决方法
- 校验规则取值逻辑错误,缺少非空判断
你开启了文件输入的multiple属性,选中文件后传给Yup校验的value是FileList类数组对象,不是单个File对象。你第二个校验规则直接取value.type本身就不成立,而且如果value为空时直接访问value[0]自然会抛出undefined错误,需要先做前置值存在判断。
修复后的校验规则代码:
const validationSchema = Yup.object().shape({ photo: Yup.mixed() .required("You need to provide a file") .test("fileSize", "File Size is too large", (value) => { // 先判断值存在且有选中文件 if (!value || value.length === 0) return false; console.log(value[0].size); return value[0].size <= 5242880; }) .test("fileType", "Unsupported File Format", (value) => { if (!value || value.length === 0) return false; return ["image/jpeg", "image/png", "image/jpg"].includes(value[0].type); }), });
- 自定义输入框缺少register返回的ref绑定
调用register("photo")返回的对象包含onChange、onBlur、ref三个必须属性,你目前仅绑定了onChange,缺少ref绑定会导致React Hook Form无法正确关联输入框DOM,出现值同步异常的问题。
修复后的PhotoHolder.js代码:
const PhotoHolder = () => { const { register } = useFormContext(); const validator = register("photo"); return ( <Input name="photo" type="file" multiple ref={validator.ref} // 新增ref绑定 onBlur={validator.onBlur} // 建议补充onBlur适配其他校验场景 onChange={(e) => { validator.onChange(e); }} /> ); };
- 可选兼容方案
如果你用的自定义Input组件不支持原生ref绑定,可以用setValue手动同步表单值,替换原有onChange逻辑即可:
const PhotoHolder = () => { const { setValue } = useFormContext(); return ( <Input name="photo" type="file" multiple onChange={(e) => { // 手动把选中的FileList同步到表单 setValue("photo", e.target.files, { shouldValidate: true }); }} /> ); };
内容的提问来源于stack exchange,提问作者some nooby questions
相关产品推荐
相关产品推荐

