NextJS15+react-hook-form+Zod表单提交时File对象被识别为字符串问题
问题原因与解决方案:React Hook Form 文件输入提交时变为 FakePath 字符串
问题原因
你在文件输入的onChange事件中同时调用了handleImageUpload(通过form.setValue设置真实的File对象)和field.onChange(e)。React Hook Form的field.onChange会默认读取文件输入框的value属性——也就是浏览器为了安全伪装的C:\FakePath\...字符串,这个操作会直接覆盖你之前用form.setValue设置的File实例,最终导致提交时拿到的是字符串而非File对象,触发Zod的instanceof(File)校验错误。
解决方案
1. 移除冲突的field.onChange(e)调用
既然已经通过form.setValue手动管理字段值,就不需要再让React Hook Form自动处理输入变更,避免值被覆盖。修改后的文件输入组件:
<Input type="file" accept="image/*" onChange={(e) => { handleImageUpload(e, index); // 移除这一行:field.onChange(e); }} />
2. 优化Zod校验(可选)
如果需要更严谨的文件校验逻辑,可以给Zod的File校验添加额外规则,比如限制文件类型、大小:
const formSchema = z.object({ // ...其他字段 media: z.instanceof(File) .optional() .nullable() .refine(file => !file || file.type.startsWith('image/'), '请上传图片格式文件') .refine(file => !file || file.size <= 2 * 1024 * 1024, '图片大小不能超过2MB'), // ...其他字段 })
3. 验证字段值的正确性
可以通过form.watch实时监控media字段的值,确认是否正确设置为File对象:
const mediaValue = form.watch(`questions.${index}.media`); console.log(mediaValue); // 应该输出File实例而非字符串
内容的提问来源于stack exchange,提问作者Lucas Mahé-Boisneau
相关产品推荐
相关产品推荐

