Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react cannot use fileinput twice without refreshing the page

I'm using html fileinput to upload a file with reactjs, but once I uploaded a file, I cannot call the function to upload another file, unless I refresh the page of course.

A simplified version of my code would be:

class Matrice extends React.Component {
  constructor(props) {
    super(props);
    this.fileInput = null;
  }

  uploadQuestion = async e => {
    console.log("uploading question");
    if (e.target.files[0]) {
      const form = new FormData();
      let type;
      if (e.target.files[0].type == "image/jpeg") type = ".jpg";
      if (e.target.files[0].type == "image/png") type = ".png";
      if (e.target.files[0].type == "image/gif") type = ".gif";
      // const fileName = this.props.current + type;
      form.append("files", e.target.files[0]); //filename
      form.append("ref", "exam"); // model
      form.append("refId", this.props.match.params.id); // id
      form.append("field", "media"); // name of field (image field)
      this.setState({ questionUploadLoading: true });
      const files = await strapi.upload(form);
      this.saveMontage(files, undefined, "question");
    }
  };

  render() {
    return (
      <>
        <input
          style={{ display: "none" }}
          ref={fileInput => (this.fileInput = fileInput)}
          onChange={this.uploadQuestion}
          className="file"
          type="file"
          id="imgAdd"
        />
        <button
          onClick={() => this.fileInput.click()}
          type="button"
          className="btn btn-secondary"
        >
          <i className="fas fa-image" />
        </button>
      </>
    );
  }
}

But my function uploadQuestion cannot be called again once I finished uploading a file. Namely, the console.log('uploading question') doesn't show up (the second time).

I don't know what could be the reason, but I guess that something is preventing the onChange handler as if, uploading a file the second time doesn't "changes" the trigger.

Does anybody have an idea what could cause this?

Thanks

like image 688
sir-haver Avatar asked Dec 14 '22 12:12

sir-haver


2 Answers

You can reset the file input by setting its value to the empty string, and you will be able to use it again.

uploadQuestion = async (e) => {
    console.log('uploading question')
    if (e.target.files[0]) {
        // ...
        this.fileInput.value = "";
    }
}
like image 180
Tholle Avatar answered Mar 07 '23 18:03

Tholle


You need to set the state for image that to be upload there is flow the step

  1. Set a state for upload file in your Constructor (uploadFile:null)

  2. Add a function for handle file Change

  3. Use state upload(uploadFile) into uploadQuestion() instead of e.target.value[0]

  4. After Upload setState back to uploadFile:null

  5. set the file input onChange={this.fileHandle}

class Matrice extends React.Component {
    constructor(props) {
        super(props);
        this.state:{
            uploadFile:null
        }
        this.fileInput = null;
        this.fileHandle = this.fileHandle.bind(this)
    }

fileHandle (e, a) {
    e.preventDefault()
    this.setState({ upload: e.target.files[0] })
  };

uploadQuestion = async (e) => {
    console.log('uploading question')
    if (e.target.files[0]) {
        const form = new FormData();
        let type;
        if (e.target.files[0].type == 'image/jpeg') type = '.jpg'
        if (e.target.files[0].type == 'image/png') type = '.png';
        if (e.target.files[0].type == 'image/gif') type = '.gif';
        // const fileName = this.props.current + type;
        //Use state upload(uploadFile) into uploadQuestion() instead of e.target.value[0]
        file.append('images', this.state.uploadFile, this.state.uploadFile.name) //filename
        form.append('ref', 'exam'); // model
        form.append('refId', this.props.match.params.id) // id
        form.append('field', 'media') // name of field (image field)
        this.setState({questionUploadLoading: true})
        const files = await strapi.upload(form);
        this.saveMontage(files, undefined, 'question')
        //After Upload setState back to uploadFile:null
        this.setState({uploadFile:null})
    }

}

if you like to valid in onChange you can modify function as Below


fileHandle (e) {
    e.preventDefault()
    if (!e.target.files[0].name.match(/.(jpg|jpeg|png|gif)$/i)) {
      this.setState({ errorMsg: 'Please upload valid file. Allowed format jpg, jpeg, png, gif' })
      return false
    } else {
      this.setState({ upload: e.target.files[0], errorMsg: '' })
    }
  };

like image 26
Dwarka Tiwari Avatar answered Mar 07 '23 16:03

Dwarka Tiwari