如何允许输入类型=文件在反应组件中选择相同的文件
Posted
技术标签:
【中文标题】如何允许输入类型=文件在反应组件中选择相同的文件【英文标题】:How to allow input type=file to select the same file in react component 【发布时间】:2017-01-21 22:22:52 【问题描述】:我有一个反应组件,它呈现一个<input type="file">
dom 以允许用户从浏览器中选择图像。我发现当我选择同一个文件时,它的 onChange 方法没有被调用。经过一番搜索,有人建议在 onChange 方法的末尾使用this.value=null
或return 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 中工作。
【问题讨论】:
这只是与反应无关的浏览器行为,文件没有改变。见***.com/questions/4109276/… 这能回答你的问题吗? html input file selection event not firing upon selecting the same file 【参考方案1】:this thread的副本
<input id="upload" ref="upload" type="file" accept="image/*"
onChange=(event)=>
this.readFile(event)
onClick=(event)=>
event.target.value = null
/>
【讨论】:
这对我有用!我不建议使用内联函数,但这个概念很有效。 使用 TypeScript,event.target.value = null
我得到了编译错误TS2322: Type 'null' is not assignable to type 'string'.
但我可以说event.target.value = ""
并且按照***.com/a/56258902/2848676 工作【参考方案2】:
我认为您的函数中的this
没有引用input
字段。尝试改用event.target
。
<input id="upload" ref="upload" type="file" accept="image/*"
onChange=(event)=>
this.readFile(event)
event.target.value=null
/>
【讨论】:
我刚试过,但它不起作用。第二次选择同一个文件时不会触发onChange方法。 使用onInput
而不是onChange
设置 event.target.value=null
对我有用,谢谢!【参考方案3】:
对我来说确实有效:event.currentTarget.value = null
onClick=(event)=>
event.currentTarget.value = null
【讨论】:
打字稿版本类似于(event.target as HTMLInputElement).value = null;
【参考方案4】:
我的 React 版本:16.2.0
@jbsmoove 解决方案适用于除 IE11 以外的所有浏览器。
对于 IE11,如果我们打开某个文件并且第二次按取消而不是打开文件,它会显示空白屏幕,在控制台中我们会看到:
无法获取未定义或空引用的属性“名称”
所以我想出了另一种即使在 IE11 中也能完美运行的解决方案:
<input id="upload" ref="upload" type="file" accept="image/*"
onInput=(event)=>
this.readFile(event)
onClick=(event)=>
event.target.value = null
/>
只需使用 onInput 而不是 onChange。
【讨论】:
【参考方案5】:以下是我的解决方案。 (使用打字稿)
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>;
【讨论】:
这个回答是不是忽略了它应该调用event.target.value = ""
的要点。或者更具体地说<input alt="Upload Demand" type="file" onChange= (ie) => this.handleUploadDemand(ie); ie.target.value = ""/>
【参考方案6】:
使用后备点击方法来选择相同的图像。 示例:
<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)
/>
【讨论】:
【参考方案7】:我通常只在输入上使用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()
(如果您在文件处理后不关心表单内容,则可行)。
【讨论】:
【参考方案8】:我通过使用 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 = "";
;
【讨论】:
以上是关于如何允许输入类型=文件在反应组件中选择相同的文件的主要内容,如果未能解决你的问题,请参考以下文章