Html 如何重置JS文件输入

Html 如何重置JS文件输入,html,reactjs,file-upload,Html,Reactjs,File Upload,我有文件上传输入: <input onChange={this.getFile} id="fileUpload" type="file" className="upload"/> 若我上传同一个文件两次,那个么上传事件不会被触发。我怎样才能解决这个问题?对于简单的js代码,只需执行以下操作即可:this.value=null;在变更处理程序中。如何使用ReactJS执行此操作?我想您可以这样清除输入值: e.target.value = null; 文件输入无法控制,没有特定的方

我有文件上传输入:

<input onChange={this.getFile} id="fileUpload" type="file" className="upload"/>

若我上传同一个文件两次,那个么上传事件不会被触发。我怎样才能解决这个问题?对于简单的js代码,只需执行以下操作即可:this.value=null;在变更处理程序中。如何使用ReactJS执行此操作?

我想您可以这样清除输入值:

e.target.value = null;
文件输入无法控制,没有特定的方法来控制



编辑对于旧浏览器(对我有效的是为文件输入设置一个
属性,然后当我需要重置它时,我更新键属性值:

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>
  )
}
重置文件输入()的函数{ 让randomString=Math.random().toString(36); 这是我的国家({ 输入键:随机字符串 }); } render(){ 返回( ) }
这将迫使我重新开始渲染输入。

这对我来说很有用-ref={ref=>This.fileInput=ref}

<input id="file_input_file" type="file" onChange={(e) => this._handleFileChange(e)} ref={ref=> this.fileInput = ref} />

我知道文件输入总是不受控制的,但是下面的代码仍然在我自己的项目中工作,我可以重置输入而没有任何问题

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} />
    );
}
构造函数(道具){
超级(道具);
此.state={
selectedFile:未定义,
selectedFileName:未定义,
imageSrc:未定义,
值:“”
};
this.handleChange=this.handleChange.bind(this);
this.removeImage=this.removeImage.bind(this);
}
手变(活动){
if(event.target.files[0]){
这是我的国家({
selectedFile:event.target.files[0],
selectedFileName:event.target.files[0]。名称,
imageSrc:window.URL.createObjectURL(event.target.files[0]),
值:event.target.value,
});
}
}
//调用此函数重置输入
removeImage(){
这是我的国家({
selectedFile:未定义,
selectedFileName:未定义,
imageSrc:未定义,
值:“”
})
}
render(){
返回(
);
}

这是我使用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;
类文件输入扩展了React.Component{
构造函数(){
超级();
this.deleteImage=this.deleteImage.bind(this);
}
deleteImage(){
//仅仅将input ref值设置为null对redux表单不起作用
//与此同时,光是呼吁变革而不采取任何行动并没有起到效果
//仅使用onChange在redux表单中进行更改,但是如果您尝试选择
//同样的图像,它没有显示在预览中,这会导致
//未调用输入,因为输入的值未更改
//但对于redux,表单将是。
this.fileInput.value=null;
this.props.input.onChange();
}
render(){
const{input:{onChange,value},accept,disabled,error}=this.props;
const{edited}=this.state;
返回(
{/*ref和on change是此处的关键属性*/}
onChange(e.target.files[0])}
多重={false}
accept={accept}
捕获
ref={(输入)=>{this.fileInput=input;}}
disabled={disabled}
/>
{!价值?
{/*添加按钮*/}
this.fileInput.click()}
disabled={disabled}
/>
:
{/*图像预览*/}
{/*此按钮不执行反替换操作*/}
this.fileInput.click()}
disabled={disabled}
/>
{/*此按钮是执行反删除操作的按钮*/}
{错误&&
{错误}
}
}
);
}
}
FileInput.propTypes={
输入:object.isRequired,
接受:字符串,
残疾人士:布尔,,
错误:字符串
};
FileInput.defaultProps={
接受:“*”,
};
导出默认文件输入;

如果您知道不打算使用内置的文件输入值,也可以将其包含在输入元素中

<input value={""} ... />


这样,在渲染时,值总是重置为空字符串,您不必在onChange函数中笨拙地包含它。

我通过更新文件输入中的
键来实现。
这将强制重新渲染,以前选择的文件将消失

<input type="file" key={this.state.inputKey} />

更改状态
inputKey
将重新呈现组件。
更改
inputKey
的一种方法是,只要单击一个按钮,就可以将其设置为
Date.now()

每次单击
onClick
都可以重置输入,这样即使使用相同的文件
onChange
也会被触发

<input onChange={this.onChange} onClick={e => (e.target.value = null)} type="file" />
(e.target.value=null)}type=“文件”/>

以下内容是使用React钩子为我工作的。这是使用所谓的“受控输入”来完成的。这意味着,输入由状态控制,或者说它们的真实来源是状态

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>
    )
};
函数CreatePost({user}){
const[content,setContent]=React.useState(“”);
const[image,setImage]=React.useState(null);//请参阅支持文档#1
const imageInputRef=React.useRef();//请参阅支持文档#2
函数handleSubmit(事件){
event.preventDefault();//停止讨厌的默认重载函数
setContent(“”;//重置第一个输入的值-请参见#1
//////开始文件输入重置
imageInputRef.current.value=“”;//重置文件输入的文件名-请参阅#2
setImage(null);//重置文件输入的值-请参见#1
//////文件结束输入重置
}
返回(
setContent(event.target.value)}
value={content}//生成此输入的值,由状态控制
/>
塞蒂姆
<input onChange={this.onChange} onClick={e => (e.target.value = null)} type="file" />
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>
    )
};
import React from "react";
import { Button } from "reactstrap";

class FileUpload extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedFile: null,
      fileInputKey: Date.now(),
      message: ""
    };
    this.handleClear = this.handleClear.bind(this);
    this.onClickHandler = this.onClickHandler.bind(this);
    this.onChangeHandler = this.onChangeHandler.bind(this);
  }

  onChangeHandler = event => {
    this.setState({
      selectedFile: event.target.files
    });
  };

  onClickHandler = () => {
    if (this.state.selectedFile === null) {
      this.setState({
        message: "Please select File"
      });
      return;
    }
    //axios POST req code to send file to server
    {
      /**        
         const data = new FormData()
    data = this.state.selectedFile[0]                
      axios.post("http://localhost:8080/api/uploadFile/", data)
               .then(res => { 
             if (res.status == 200) {
           // upload success
             }                
               })
               .catch(err => { 
                  //message upload failed
               })    
    */
    }
//after upload to server processed

    this.setState({
      selectedFile: null,
      fileInputKey: Date.now(),
      message: "File Uploaded"
    });
  };

  handleClear() {
    this.setState({
      selectedFile: null,
      fileInputKey: Date.now(),
      message: ""
    });
  }

  render() {
    return (
      <div>
        <input
          type="file"
          key={this.state.fileInputKey}
          class="form-control"
          onChange={this.onChangeHandler}
        />
        <button
          type="button"
          class="btn btn-success btn-block"
          onClick={this.onClickHandler}
        >
          Upload
        </button>
        <Button
          type="button"
          value="Clear"
          data-test="clear"
          onClick={this.handleClear}
        >
          {" "}
          Clear{" "}
        </Button>

        <br />
        <label>{this.state.message}</label>
      </div>
    );
  }
}

export default FileUpload;