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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 12:31:01