input[type='file'] 连续上传同一个文件不触发 onChange 事件 或 Upload 组件只调用了一次 onChange 函数

input[type='file'] 连续上传同一个文件不触发 onChange 事件 或 Upload 组件只调用了一次 onChange 函数

原因为 onChange 的触发条件是 value的变化。当我们选取文件上传后,value的值为该文件在磁盘中的地址。如:D:\test\1.docx 。因此,我们改变value值即可。

背景一:原生input

如果使用的是原生input标签,只需在点击事件的时候置空value值即可。

 {
    (e.target as HTMLInputElement).value = "";
  }}
  onChange={(e) => {
    console.log(`e`, e.target.files);
  }}
/>

背景二:采用了AntdInput组件上传file

此时不能直接的使用背景一的方法去改变value,否则你会得到以下信息:

Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

翻译为:无法在“HTMLInputElement”上设置“value”属性:此输入元素接受文件名,该文件名只能以编程方式设置为空字符串。

这对于文件输入无效,因为浏览器只允许读取而不是写入输入。

可调用Input身上的setValue(value: string, callback?: () => void): void方法,即可解决。

 {
    uploadIptRef.current?.setValue("");
  }}
  onChange={(e) => {
    console.log(`e`, e.target.files);
  }}
/>;

setValueant-design\components\input\Input.tsx中表现为

setValue(value: string, callback?: () => void) {
    if (this.props.value === undefined) {
        this.setState({ value }, callback);
    } else {
        callback?.();
    }
}

渲染组件

renderComponent = ({ getPrefixCls, direction, input }: ConfigConsumerProps) => {
  const { value, focused } = this.state;
  const { prefixCls: customizePrefixCls, bordered = true } = this.props;
  const prefixCls = getPrefixCls("input", customizePrefixCls);
  this.direction = direction;

  return (
    
      {(size) => (
        
      )}
    
  );
};

背景三:采用了Ant designUpload组件,遇到onChange只调用一次问题

可参考 #2423

你可能感兴趣的:(input[type='file'] 连续上传同一个文件不触发 onChange 事件 或 Upload 组件只调用了一次 onChange 函数)