I want to create a file upload feature in react using React dnd, where a user should be able to upload files by dropping them in a div
3 Answers
Hello i suggest this solution -
<div
className="file-select"
onDragOver={dragOver}
onDragEnter={dragEnter}
onDragLeave={dragLeave}
onDrop={fileDrop}
onClick={fileInputClicked}
>
<h4>Select File</h4>
<input
ref={fileInputRef}
className="file-input"
type="file"
multiple
onChange={filesSelected}
/>
</div>
also suggest using ref:
const fileInputRef = useRef();
It's only skeleton - You need to implement those methods - take validation into account - what files are supported etc.
In addition, you can implement file preview, deletion etc. - so the design or at least the concept of the solution is important in this case
For example i using this function for multi-select:
const [selectedFiles, setSelectedFiles] = useState([]);
const [validFiles, setValidFiles] = useState([]);
const [unsupportedFiles, setUnsupportedFiles] = useState([]);
const filesSelected = () => {
if (fileInputRef.current.files.length) {
handleFiles(fileInputRef.current.files);
}
};
const handleFiles = (files) => {
for (let i = 0; i < files.length; i++) {
if (validateFile(files[i])) {
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
} else {
files[i].invalid = true;
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
setErrorMessage('File type not permitted');
setUnsupportedFiles((prevArray) => [...prevArray, files[i]]);
}
}
handleFileData(files);
};

- 2,046
- 5
- 18
- 30
You can use react dropzone package for this purpose.
npm install --save react-dropzone
or:
yarn add react-dropzone
Example snippet using hooks
import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'
function MyDropzone() {
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
)
}
Example snippet using wrapper component
import React from 'react'
import Dropzone from 'react-dropzone'
<Dropzone onDrop={acceptedFiles => console.log(acceptedFiles)}>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>
Using the callback of onDrop you can get acceptedFiles array which contain files. You can also limit size, allow multiple or just one and type of files you want to accept.
An example Snippet is below with multiple images allowed of 10MB and only extensions of png,jpg,jpeg are allowed.
<Dropzone
multiple={true}
minSize={0}
maxSize={10485760}
accept="image/png,image/jpg,image/jpeg"
onDrop={acceptedFiles => console.log(acceptedFiles)}>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>

- 1,953
- 17
- 39
check out react-uploady - upload-drop-zone
You can get started with very little code, like this:
import Uploady from "@rpldy/uploady";
import UploadDropZone from "@rpldy/upload-drop-zone";
const App = () => (
<Uploady destination={{url: "https://my-server.com/upload"}}>
<UploadDropZone onDragOverClassName="drag-over">
<span>Drag&Drop File(s) Here</span>
</UploadDropZone>
</Uploady>);

- 1,001
- 10
- 14