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

React Hook Form setValue设置多文件输入框值报错问题

问题根因

这个报错是浏览器原生安全限制导致,和React Hook Form(以下简称RHF)本身逻辑无关:

  • 出于防止恶意脚本未经用户授权私自读取、上传本地文件的安全规则,所有<input type="file">元素的value属性,仅允许被程序设置为空字符串,不能直接赋值为File对象、FileList或者自定义数组。
  • 单文件场景下setValue未触发报错,是因为RHF识别到传入值为单个File实例时,不会尝试直接将值写入原生input的value属性;传入数组类型的多文件值时,RHF的默认字段注册逻辑会尝试将值同步到DOM属性,直接触发浏览器的安全拦截抛出错误。
解决方案

核心原则是:不要让RHF将表单状态中存储的File/File数组,同步写入原生file类型input的value属性,提供两种可直接落地的实现方式:

方案1:调整register配置,关闭原生值同步

给多文件输入框注册时增加特殊配置,阻断RHF向原生DOM赋值的逻辑,不影响正常的表单校验、状态收集:

// 多文件输入框注册配置
<input
  type="file"
  multiple
  {...register('multiple', {
    value: undefined, // 关键配置:禁止RHF主动给input.value赋值
  })}
/>

对应赋值逻辑补充配置项,确保表单状态正常更新:

const handleMultiple = (files, data) => {
  setValue('multiple', [...files], {
    shouldDirty: true,
    shouldTouch: true,
    shouldValidate: true
  });
};

单文件字段如果后续出现同类报错,也可以套用相同配置处理。

方案2:用Controller托管字段(推荐,适配自定义上传组件)

如果使用封装过的自定义上传组件,或者需要更灵活的值控制,直接用RHF提供的Controller组件托管字段,完全跳过默认的原生input注册逻辑,从根源避免DOM赋值操作:

import { Controller, useForm } from 'react-hook-form';

// 表单中多文件字段渲染部分
<Controller
  name="multiple"
  control={control}
  defaultValue={[]}
  render={({ field }) => (
    <input
      type="file"
      multiple
      // 仅绑定事件,不将field.value绑定到input的value属性
      onChange={(e) => {
        const selectedFiles = e.target.files;
        field.onChange(selectedFiles ? [...selectedFiles] : []);
      }}
      onBlur={field.onBlur}
    />
  )}
/>

这种方式下multiple字段的表单值始终是你需要的File对象数组,不会触发任何原生安全报错,也兼容后续的校验、提交逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:21:36