react-dropzone: Dropping Image not setting files to input.

<Dropzone onDrop={this.onDrop} className="drop-zone text-center" name="building_photo_1"
                        inputProps={{size: '30', required: "true"}}>
             <i className="fa fa-upload fa-4x"/>
             <div className="drop-zone-text">
                   {!this.state.fileNames ?<div>Select files to upload<p>or drag and drop photo files</p></div>
                   : <div>{this.state.fileNames}</div>}
             </div>
</Dropzone>

Selecting files sets the files to the input perfectly, but when dropping the file the files are not being set to the input.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 20

Most upvoted comments

As far as I can tell, it’s not possible to set the files property on a file input using javascript, so this is not a bug in react-dropzone.

The way I ended up working around this issue is by submitting the form using fetch, and storing the files that were dropped in state and adding them to a FormData instance created from the form, e.g.:

    onDrop(acceptedFiles, rejectedFiles, e) {
        this.setState({
            files: acceptedFiles,
            filesWereDropped: !e.target.files || e.target.files.length === 0
        });
    }
    onSubmit(e) {
        e.preventDefault();
        let formData = new FormData(this.formRef);

        if (this.state.filesWereDropped) {
            /* if the file input has no files, check state for files and add
             * those to the form data. This is necessary because dragging
             * and dropping does set the files property of the file input,
             * and it is not possible to set it from javascript for
             * security reasons.
             */
            this.state.files.forEach(file => {
                formData.append('myfiles', file, file.name);
            });
        }

        // then POST your formData!
    }

for anyone that have the same issue, the solution in this blog post solved my issue

https://pqina.nl/blog/set-value-to-file-input/#updating-the-file-input-files-property

  useEffect(() => {
    if (!inputRef.current) return;

    const dataTransfer = new DataTransfer();
    acceptedFiles.forEach((file) => {
      dataTransfer.items.add(file);
    });

    inputRef.current.files = dataTransfer.files;

    // Help Safari out
    if (inputRef.current.webkitEntries.length) {
      inputRef.current.dataset.file = `${dataTransfer.files[0].name}`;
    }
  }, [acceptedFiles]);

@micchyboy237, not possible, as I explained above. It’s a limitation put in place by browsers for security.

@vikalpgupta-birdeye I’m open for the PR if you know how to implement this.