我有文件上传输入:
<input onChange={this.getFile} id="fileUpload" type="file" className="upload"/>
我以这种方式处理上传:
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);
}
如果我上传同一个文件两次,则不会触发上传事件。我该如何解决这个问题?对于简单的js代码,只需执行以下操作即可:this.value = null;在变更处理程序。我怎么能用ReactJS做到这一点?
答案 0 :(得分:32)
我认为您可以像这样清除输入值:
e.target.value = null;
无法控制文件输入,没有特定于React的方法。
答案 1 :(得分:21)
这项工作对我来说 - ref = {ref =&gt; this.fileInput = ref}
<input id="file_input_file" type="file" onChange={(e) => this._handleFileChange(e)} ref={ref=> this.fileInput = ref} />
然后在我的情况下,一旦文件上传到服务器,我使用下面的语句清除它
this.fileInput.value = "";
答案 2 :(得分:13)
对我有用的是为文件输入设置void*
属性,然后当我需要重置它时,我更新了键属性值:
key
这迫使React再次从头开始渲染输入。
答案 3 :(得分:4)
我通过更新文件输入中的key
来实现。
这将强制重新渲染,并且先前选择的文件将消失。
<input type="file" key={this.state.inputKey} />
更改状态inputKey
将重新呈现组件。
更改inputKey
的一种方法是始终单击应该清除该字段的按钮,将其始终设置为Date.now()
。
答案 4 :(得分:4)
以下内容使用React Hooks为我工作。使用所谓的“受控输入”完成此操作。这就是说,输入是受国家控制的,或者它们的真实来源是国家。
TL; DR 使用useState()
和useRef()
钩子重置文件输入是一个两步过程。
注意:我还介绍了如何在其他人好奇的情况下重置文本输入。
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>
)
};
支持文档:
答案 5 :(得分:1)
如果您完全不打算使用内置文件输入值,那么也可以在输入元素中包含此内容。
<input value={""} ... />
通过这种方法,值始终在渲染时重置为空字符串,而不必在onChange函数中笨拙地包含它。
答案 6 :(得分:1)
每次点击onClick
都可以重置输入,以便即使使用相同的文件onChange
也将被触发。
<input onChange={this.onChange} onClick={e => (e.target.value = null)} type="file" />
答案 7 :(得分:0)
我知道文件输入始终不受控制,但是下面的代码仍然可以在我自己的项目中使用,我可以毫无问题地重置输入。
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} />
);
}
答案 8 :(得分:0)
这是我使用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;
答案 9 :(得分:0)
React只是JavaScript,我们也可以在React代码中使用DOM操作。 这应该可以工作
document.getElementsByClassName('upload')[0].value = null;
答案 10 :(得分:0)
我们可以使用
<mergingTracksBreakdownStructure>
<track id="10">
<mergedTrack id="10"/>
<mergedTrack id="11"/>
<mergedTrack id="12"/>
</track>
<track id="13">
<mergedTrack id="13"/>
<mergedTrack id="14"/>
</track>
<track id="15">
<mergedTrack id="15"/>
<mergedTrack id="16"/>
</track>
<track id="27">
<mergedTrack id="27"/>
</track>
<track id="30">
<mergedTrack id="30"/>
</track>
</mergingTracksBreakdownStructure>
并在构造函数状态下将<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:result-document href="output.xml" method="xml">
<xsl:apply-templates select="document('input.xml')//track"/>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
初始化为key = {this.state.fileInputKey}
来重置文件输入。
成功上传文件后,我们需要再次分配fileInputKey:Date.now(),使其具有与先前不同的值,并在下一个fileInputKey
我们还可以通过单击按钮清除/重置文件输入来手动执行此操作
下面是工作代码:
Date.now()