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

React中onSubmit函数无法获取上传文件的问题求助

解决React Hook Form无法在提交时获取上传文件的问题

问题原因

你遇到的问题是因为React Hook Form 默认不会自动跟踪 file 类型输入的状态,同时你手动绑定的 onChange 方法和组件内部的表单状态更新逻辑冲突,导致提交时无法从表单实例中拿到文件值。

两种可行解决方案

方案一:让React Hook Form自动处理文件输入(推荐)

直接利用 register 的回调来处理文件变化,无需手动调用 setValue,React Hook Form会自动维护文件状态:

import React, { useState } from 'react'
import { useForm } from 'react-hook-form'

const UploadImage = ({ course }) => {
    const [image, setImage] = useState(course.imageLink)
    const form = useForm();

    const { handleSubmit } = form;
    const { isSubmitting } = form.formState;

    const onSubmit = (data) => {
        // 直接从提交的data中获取文件
        console.log(data.imageLink);
    }

    return (
        <div className='p-10'>
            <form onSubmit={handleSubmit(onSubmit)}>
                <input
                    className='p-1 shadow-lg appearance-none rounded w-full'
                    disabled={isSubmitting}
                    {...form.register('imageLink', {
                        onChange: (e) => {
                            const file = e.target.files[0];
                            if (file) {
                                setImage(URL.createObjectURL(file));
                            }
                        }
                    })}
                    type="file"
                    id="image"
                />
                <button
                    type='submit'
                    disabled={isSubmitting}
                    className='px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-md'>
                    Save
                </button>
            </form>
            <img src={image} alt="Course preview" />
        </div>
    )
}

export default UploadImage

方案二:用独立状态存储文件(适合需自定义复杂逻辑的场景)

如果需要保留自定义的文件处理逻辑,可以直接用 useState 存储选中的文件,提交时直接读取这个状态:

import React, { useState } from 'react'
import { useForm } from 'react-hook-form'

const UploadImage = ({ course }) => {
    const [image, setImage] = useState(course.imageLink)
    const [selectedFile, setSelectedFile] = useState(null); // 新增状态存储文件
    const form = useForm();

    const { handleSubmit } = form;
    const { isSubmitting } = form.formState;

    const onSubmit = () => {
        // 直接读取自定义状态中的文件
        console.log(selectedFile);
    }

    const handleFileChange = (e) => {
        try {
            const file = e.target.files[0];
            if (file) {
                console.log(file);
                setSelectedFile(file);
                setImage(URL.createObjectURL(file));
            }
        } catch (error) {
            console.log(error);
        }
    };

    return (
        <div className='p-10'>
            <form onSubmit={handleSubmit(onSubmit)}>
                <input
                    className='p-1 shadow-lg appearance-none rounded w-full'
                    disabled={isSubmitting}
                    type="file"
                    onChange={handleFileChange}
                    id="image"
                />
                <button
                    type='submit'
                    disabled={isSubmitting}
                    className='px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-md'>
                    Save
                </button>
            </form>
            <img src={image} alt="Course preview" />
        </div>
    )
}

export default UploadImage

补充说明

原代码中调用 setValue('imageLink', file) 无法生效的核心原因是:文件对象属于特殊的 Blob 类型,React Hook Form 默认的表单状态处理机制不支持直接存储这类对象,同时手动的 onChange 覆盖了组件内部的状态同步逻辑,导致表单实例无法正确跟踪文件变化。

内容的提问来源于stack exchange,提问作者Prateek Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:22:35