Html 如何重置 ReactJS 文件输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42192346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to reset ReactJS file input
提问by Stepan Yakovenko
I have file upload input:
我有文件上传输入:
<input onChange={this.getFile} id="fileUpload" type="file" className="upload"/>
And I handle upload this way:
我以这种方式处理上传:
getFile(e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = (theFile) => {
var data = {
blob: theFile.target.result, name: file.name,
visitorId: this.props.socketio.visitorId
};
console.log(this.props.socketio);
this.props.socketio.emit('file-upload', data);
};
reader.readAsDataURL(file);
}
If I upload same file twice, then upload event is not fired. How can I fix that? For simple js code it was enough to do the following: this.value = null; in change handler. How can I do it with ReactJS?
如果我上传相同的文件两次,则不会触发上传事件。我该如何解决?对于简单的 js 代码,执行以下操作就足够了: this.value = null; 在更改处理程序中。我怎样才能用 ReactJS 做到这一点?
回答by Freez
I think you can just clear the input value like this :
我认为您可以像这样清除输入值:
e.target.value = null;
File input cannot be controlled, there is no React specific way to do that.
无法控制文件输入,没有 React 特定的方法来做到这一点。
回答by Jozcar
This work for me - ref={ref => this.fileInput = ref}
这对我有用 - ref={ref => this.fileInput = ref}
<input id="file_input_file" type="file" onChange={(e) => this._handleFileChange(e)} ref={ref=> this.fileInput = ref} />
then in my case once the file was uploaded to the server , I clear it by using the statement below
然后在我的情况下,一旦文件上传到服务器,我就会使用下面的语句清除它
this.fileInput.value = "";
回答by tonatiuhnb
What worked for me was setting a key
attribute to the file input, then when I needed to reset it I update the key attribute value:
对我有用的是key
为文件输入设置一个属性,然后当我需要重置它时,我更新了关键属性值:
functionThatResetsTheFileInput() {
let randomString = Math.random().toString(36);
this.setState({
theInputKey: randomString
});
}
render() {
return(
<div>
<input type="file"
key={this.state.theInputKey || '' } />
<button onClick={this.functionThatResetsTheFileInput()} />
</div>
)
}
That forces React to render the input again from scratch.
这迫使 React 从头开始再次渲染输入。
回答by aelor
I do it by updating key
inside my file input.
This will force a re-render and previously selected file will go away.
我通过key
在我的文件输入中更新来做到这一点。这将强制重新渲染,并且先前选择的文件将消失。
<input type="file" key={this.state.inputKey} />
Changing the state inputKey
will re-render the component.
One way to change the inputKey
will be to always set it to Date.now()
on click of a button which is supposed to clear the field.
更改状态inputKey
将重新渲染组件。更改inputKey
will 的一种方法是始终将其设置为Date.now()
单击应该清除该字段的按钮。
回答by Elnoor
With every click onClick
you can reset the input, so that even with the same file onChange
will be triggered.
每次点击onClick
都可以重置输入,这样即使是同一个文件onChange
也会被触发。
<input onChange={this.onChange} onClick={e => (e.target.value = null)} type="file" />
回答by IRTrapGod
You can also include this in your input element if you know you are not going to be using the built-in file input value at all.
如果您知道您根本不会使用内置文件输入值,您也可以将它包含在您的输入元素中。
<input value={""} ... />
This way the value is always reset to the empty string on render and you don't have to include it awkwardly in an onChange function.
通过这种方式,值总是在渲染时重置为空字符串,并且您不必笨拙地将它包含在 onChange 函数中。
回答by Hyman L.
I know file input is always uncontrolled however the following code still works in my own porject, I can reset the input with no problems at all.
我知道文件输入总是不受控制,但是以下代码在我自己的项目中仍然有效,我可以毫无问题地重置输入。
constructor(props) {
super(props);
this.state = {
selectedFile: undefined,
selectedFileName: undefined,
imageSrc: undefined,
value: ''
};
this.handleChange = this.handleChange.bind(this);
this.removeImage = this.removeImage.bind(this);
}
handleChange(event) {
if (event.target.files[0]) {
this.setState({
selectedFile: event.target.files[0],
selectedFileName: event.target.files[0].name,
imageSrc: window.URL.createObjectURL(event.target.files[0]),
value: event.target.value,
});
}
}
// Call this function to reset input
removeImage() {
this.setState({
selectedFile: undefined,
selectedFileName: undefined,
imageSrc: undefined,
value: ''
})
}
render() {
return (
<input type="file" value={this.state.value} onChange={this.handleChange} />
);
}
回答by Agustina Chaer
Here is my solution using redux form
这是我使用 redux 形式的解决方案
class FileInput extends React.Component {
constructor() {
super();
this.deleteImage = this.deleteImage.bind(this);
}
deleteImage() {
// Just setting input ref value to null did not work well with redux form
// At the same time just calling on change with nothing didn't do the trick
// just using onChange does the change in redux form but if you try selecting
// the same image again it doesn't show in the preview cause the onChange of the
// input is not called since for the input the value is not changing
// but for redux form would be.
this.fileInput.value = null;
this.props.input.onChange();
}
render() {
const { input: { onChange, value }, accept, disabled, error } = this.props;
const { edited } = this.state;
return (
<div className="file-input-expanded">
{/* ref and on change are key properties here */}
<input
className="hidden"
type="file"
onChange={e => onChange(e.target.files[0])}
multiple={false}
accept={accept}
capture
ref={(input) => { this.fileInput = input; }}
disabled={disabled}
/>
{!value ?
{/* Add button */}
<Button
className="btn-link action"
type="button"
text="Add Image"
onPress={() => this.fileInput.click()}
disabled={disabled}
/>
:
<div className="file-input-container">
<div className="flex-row">
{/* Image preview */}
<img src={window.URL.createObjectURL(value)} alt="outbound MMS" />
<div className="flex-col mg-l-20">
{/* This button does de replacing */}
<Button
type="button"
className="btn-link mg-b-10"
text="Change Image"
onPress={() => this.fileInput.click()}
disabled={disabled}
/>
{/* This button is the one that does de deleting */}
<Button
type="button"
className="btn-link delete"
text="Delete Image"
onPress={this.deleteImage}
disabled={disabled}
/>
</div>
</div>
{error &&
<div className="error-message"> {error}</div>
}
</div>
}
</div>
);
}
}
FileInput.propTypes = {
input: object.isRequired,
accept: string,
disabled: bool,
error: string
};
FileInput.defaultProps = {
accept: '*',
};
export default FileInput;
回答by Dani Amsalem
The following worked for me using React Hooks. This is done using what is known as a "controlled input". That means, the inputs are controlledby state, or their source of truth is state.
以下使用 React Hooks 对我有用。这是使用所谓的“受控输入”完成的。这意味着,输入由状态控制,或者它们的真实来源是状态。
TL;DRResetting the file input was a two-step process using both the useState()
and useRef()
hooks.
TL;DR重置文件输入是一个使用钩子useState()
和useRef()
钩子的两步过程。
NOTE: I also included how I reset a text input in case anyone else was curious.
注意:我还包括了如何重置文本输入以防其他人好奇。
function CreatePost({ user }) {
const [content, setContent] = React.useState("");
const [image, setImage] = React.useState(null); //See Supporting Documentation #1
const imageInputRef = React.useRef(); //See Supporting Documentation #2
function handleSubmit(event) {
event.preventDefault(); //Stop the pesky default reload function
setContent(""); //Resets the value of the first input - See #1
//////START of File Input Reset
imageInputRef.current.value = "";//Resets the file name of the file input - See #2
setImage(null); //Resets the value of the file input - See #1
//////END of File Input Reset
}
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Add Post Content"
onChange={event => setContent(event.target.value)}
value={content} //Make this input's value, controlled by state
/>
<input
type="file"
onChange={event => setImage(event.target.files[0])} //See Supporting Doc #3
ref={imageInputRef} //Apply the ref to the input, now it's controlled - See #2
/>
<button type="submit">Submit Form</button>
</form>
</div>
)
};
Supporting Documentation:
支持文档:
- useState Hook
- Returns a stateful value, and a function to update it.
- useRef Hook
- If you pass a ref object to React, React will set its current property to the corresponding DOM node whenever that node changes.
- Using files from web apps
- If the user selects just one file, it is then only necessary to consider the first file of the list.
- 使用状态钩子
- 返回一个有状态的值和一个更新它的函数。
- 使用引用钩子
- 如果您将 ref 对象传递给 React,则每当该节点发生更改时,React 都会将其当前属性设置为相应的 DOM 节点。
- 使用来自网络应用程序的文件
- 如果用户只选择一个文件,则只需要考虑列表的第一个文件。