如何允许输入类型=file在react组件中选择相同的文件

How to allow input type=file to select the same file in react component

本文关键字:选择 文件 组件 react 输入 何允许 类型 file      更新时间:2023-09-26

我有一个react组件,它呈现一个<input type="file"> dom,允许用户从浏览器中选择图像。我发现当我选择相同的文件时,它的onChange方法没有被调用。经过一番搜索,有人建议在onChange方法结束时使用this.value=nullreturn false,但我尝试过它不起作用。

下面是我的代码:
<input id="upload" ref="upload" type="file" accept="image/*"
           onChange={(event)=> { this.readFile(event) }}/>

下面是我的尝试:

<input id="upload" ref="upload" type="file" accept="image/*"
               onChange={(event)=> { 
                   this.readFile(event) 
                   return false
              }}/>

另一个是:

<input id="upload" ref="upload" type="file" accept="image/*"
           onChange={(event)=> { 
               this.readFile(event) 
               this.value=null
          }}/>

我相信上面的解决方案适用于jquery,但我不知道如何让它在reactjs中工作

此线程结束

<input id="upload" ref="upload" type="file" accept="image/*"
           onChange={(event)=> { 
               this.readFile(event) 
          }}
        onClick={(event)=> { 
               event.target.value = null
          }}
/>

我认为你的函数中的this不是指input字段。试着用event.target代替。

<input id="upload" ref="upload" type="file" accept="image/*"
           onChange={(event)=> { 
               this.readFile(event) 
               event.target.value=null
          }}/>

对于我来说实际上是有效的:event. currentarget 。Value = null

    onClick={(event)=> { 
               event.currentTarget.value = null
          }}

经过几个小时的在线研究,这对我在Reactjs上起作用

<input id="upload" ref="upload" type="file" accept="image/*"
           onChange={(event)=> { 
               //to do
          }}
        onClick={(e)=> { 
               e.target.value = null
          }}
/>

我的React版本:16.2.0

@jbsmoove解决方案适用于除IE11以外的所有浏览器。

对于IE11,如果我们打开一些文件,在第二次我们按取消而不是打开文件,它显示空屏幕,在控制台上我们看到:

无法获取未定义或空引用的属性'name'

所以我想出了另一个解决方案,即使在IE11中也能完美地工作:

<input id="upload" ref="upload" type="file" accept="image/*"
      onInput={(event)=> { 
           this.readFile(event) 
      }}
      onClick={(event)=> { 
           event.target.value = null
      }}
/>

只使用 onInput onChange

我的解决方案如下:(使用打印稿)

import * as React from "react";
export class FileSelector extends React.Component<undefined, undefined>
{
    constructor(props: any)
    {
        super(props);
        this.handleChange = this.handleChange.bind(this);
    }
    handleChange(selectorFiles: FileList)
    {
        console.log(selectorFiles);
    }
    render ()
    {
        return <div>
            <input type="file" onChange={ (e) => this.handleChange(e.target.files) } />
        </div>;
    }
}

没有断言的Typescript方式

  <input
      id="upload"
      ref="upload"
      type="file"
      accept="image/*"
      onChange={(e: ChangeEvent<HTMLInputElement>) => {
                this.readFile(e)
      }}
      onClick={(e: MouseEvent<HTMLInputElement>) => {
                e.currentTarget.value = "";
      }}
   />

使用on-Click方法选择相同的图像。例子:

  <input
    id="upload" 
    ref="upload" 
    type="file" 
    accept="image/*"       
    multiple="false"
    onChange={(e) => this.getDailyImage(e)}
    onClick={(e) => e.target.files[0] && this.getDailyImage(e)}
  />

我通常只是在输入上使用key prop来重置它在选择之间的底层DOM节点(在更改处理程序中使用一些增量UID计数器或上传/处理状态标志):

const UploadInput = (props) => {
  const [isUploading, setUploading] = useState(false);
  const handleChange = useCallback((async (e) => {
    setUploading(true); // or setUID((old) => old + 1);
    try {
      await ... // handle processing here
    } finally {
      setUploading(false);
    }
  }, [...]);
  return (
    <div className={...}>
      <input key={isUploading} type="file" onChange={handleChange} {...props} />
      {isUploading && <Spinner />}
    </div>
  );
};
另一种方法可能是获取表单的ref并在处理后使用formRef.reset()(如果您不关心文件处理后的表单内容,则可行)。

我通过使用Typescript在我的input中添加以下onchange事件侦听器来工作。

const onInputFileChange = (
  event: ChangeEvent<HTMLInputElement>
): void => {
  const nativeEvent = event.nativeEvent.target as HTMLInputElement;
  const targetEvent = event.target as HTMLInputElement;
  if (targetEvent.files && targetEvent.files[0]) {
    const imageFile = targetEvent.files[0];
    // eslint-disable-next-line no-param-reassign
    nativeEvent.value = "";
  }
};

如果您正在使用多个文件上传,请尝试 currentarget .value

  <input id='uploadFile' type="file" onClick={(e)=> {e.currentTarget.value = null}}  onChange={onChangeGetFilesSelected}  multiple={true} accept=".xlsx,.xls,.doc, .docx,.ppt, .pptx,.txt,.pdf"/>

如果我们想多次更新同一个文件(相同的名称),我们会得到上面的错误。为了避免这种情况,我们需要在第一次更新文件后为currentttarget分配空值。

const handleFile = useCallback(e => {
    const MAX_FILE_SIZE = (fileSize.MAX_FILE_SIZE_MANAGE_TAGS * 1024)
    if (e.target.files.length > 0) {
        const uploadedFileSize = e.target.files[0].size / 1024
        if (uploadedFileSize < MAX_FILE_SIZE) {
            uploadFile(e.target.files[0]) // you will get current uploaded value
            e.currentTarget.value = null // this the place where we need to assign null value
        } else {
            console.log('file is large')
        }
    }
}, [ ])

<Button
    className={classes.uploadButton}
    component="label"
>
    Upload File
    <input
        onChange={handleFile}
        type="file"
        accept=".xlsx"
        hidden
    />
</Button>

这迫使它每次都'更改'文件,即使再次选择相同的文件。

<input type="file" value="" />