React Hook Form用Controller声明file输入默认值不生效问题
React Hook Form 中 Controller 对接 type=file 输入框的正确方案
失效核心原因
文件输入框是原生特殊表单控件,它的value属性是只读的,只允许用户通过系统文件选择器修改,不支持外部通过JS赋值。当前代码直接把Controller返回的field全量展开到TextField上,会把RHF里存的默认值(通常是空字符串/undefined)强行绑定到输入框的value属性上,同时默认的onChange逻辑只会取e.target.value的假路径字符串,不会存真实的File对象,最终导致功能异常、默认值不生效。
实现步骤
- 配置
useForm时,给file字段设置正确的默认值,必须为undefined,不能使用空字符串、null等其他类型值
const { control, handleSubmit, formState: { errors } } = useForm({ defaultValues: { file: undefined } });
- 编写Controller渲染逻辑时,过滤掉
field中自带的value属性,手动接管onChange事件,把选中的真实File对象同步给RHF,同时正确绑定ref
修正后的完整代码
<Controller control={control} name="file" rules={{ required: "该字段为必填项*." }} render={({ field: { onChange, value, ref, ...restField } }) => ( <TextField id="file" label="上传PDF格式简历" variant="outlined" fullWidth margin="normal" type="file" InputLabelProps={{ shrink: true }} inputProps={{ accept: "application/pdf" }} {...restField} inputRef={ref} onChange={(e) => { // 取出选中的第一个文件,传给RHF存储 const selectedFile = e.target.files?.[0]; onChange(selectedFile); }} error={Boolean(errors?.file)} helperText={errors.file?.message} /> )} />
提交时的使用方式
表单提交时拿到的data.file就是用户选中的File实例,可以直接塞入FormData传给后端:
const onSubmit = (data) => { const uploadForm = new FormData(); uploadForm.append('resume', data.file); // 调用上传接口传入uploadForm即可 };
注意事项
- 不要给file字段设置空字符串、null等非File/undefined类型的默认值,会触发原生file输入的只读限制
- 不要透传field的value属性到输入框,file输入的value是浏览器生成的安全假路径,没有存储价值,RHF中只需要存真实的File对象
- 如果需要做重置操作,调用
reset()方法时file字段依旧传undefined即可清空选择
内容的提问来源于stack exchange,提问作者nishikant singh
相关产品推荐
相关产品推荐

