Drag and Drop File Upload in React using react-dropzone-uploader
In this article we’ll show you how to implement drag and drop file upload in React using react-dropzone-uploader. With the help of the npm package we can easily create a react component for handling the dragging and dropping of the documents such as media file, text file, doc file etc.
Previously, we have written an article that explains how to upload an image in React using Node.js file upload API. Therefore in this article, we’ll implement the drag and drop feature in the React application.
Steps to implement drag and drop file upload in React
- Setup react application
- Install dropzone package
- Integrate dropzone package
- Design the preview component
- Integrate file upload API
- Output
1. Setup react application
First, we will set up a react application using create-react-app
. If you don’t know then refer this article to create an application.
2. Install dropzone package
As we mentioned, we will use the react-dropzone-uploader npm package to implement drag and drop feature.
Run the following command to install the dropzone package.
1 | npm i react-dropzone-uploader |
3. Integrate dropzone package
To integrate the dropzone package, first we have to import the package along with the style.
1 2 | import 'react-dropzone-uploader/dist/styles.css'; import Dropzone from 'react-dropzone-uploader'; |
Now let’s create a couple of functions that we will use in the dropzone module.
1 2 3 4 5 6 7 8 9 | // specify upload params and API url to file upload const getUploadParams = ({ meta, file }) => { return { url: '<FILE_UPLOAD_API_URL>' } } // handle the status of the file upload const handleChangeStatus = ({ meta, file }, status) => { console.log(status, meta, file) } |
Use the above functions in dropzone for rendering in the component.
1 2 3 4 5 | <Dropzone getUploadParams={getUploadParams} onChangeStatus={handleChangeStatus} accept="image/*,audio/*,video/*" /> |
4. Design the preview component
We can also modify the dropzone by adding the custom style and components. Please check out the following code to modify the dropzone and display progress of the file upload with status.
1 2 3 4 5 6 7 8 9 10 11 | <Dropzone getUploadParams={getUploadParams} onChangeStatus={handleChangeStatus} styles={{ dropzone: { overflow: 'auto', border: '1px solid #999', background: '#f5f5f5' }, inputLabelWithFiles: { margin: '20px 3%' } }} canRemove={false} PreviewComponent={Preview} accept="image/*,audio/*,video/*" /> |
Over here we have customized the preview component and that looks like below.
1 2 3 4 5 6 7 8 9 | // preview component const Preview = ({ meta }) => { const { name, percent, status, previewUrl } = meta; return ( <div className="preview-box"> <img src={previewUrl} /> <span className="name">{name}</span> - <span className="status">{status}</span>{status !== "done" && <span className="percent"> ({Math.round(percent)}%)</span>} </div> ) } |
index.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | .preview-box { display:flex; align-items:center; width: calc(100% - 30px); padding: 10px 3%; background: #fff; border-bottom: 1px solid #ddd; font-size: 14px; } .preview-box img { max-height: 80px; max-width: 80px; border-radius: 4px; margin-right: 10px; } .preview-box .name { font-style: italic; color: #666; margin-right: 7px; } .preview-box .percent { font-weight: 600; } .preview-box .status { margin-left: 7px; font-weight: 600; text-transform: uppercase; } |
Check out this link for more information regarding the props.
5. Integrate file upload API
It’s time to upload a file on the server using the rest API. We have already created an API to upload files in Node.js.
We have to update the following functions to integrate API. For now we are using the http://localhost:4000/uploadmultifile
Node.js API to upload files on the server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // specify upload params and API url to file upload const getUploadParams = ({ file }) => { const body = new FormData(); body.append('dataFiles', file); return { url: 'http://localhost:4000/uploadmultifile', body } } // handle the status of the file upload const handleChangeStatus = ({ xhr }) => { if (xhr) { xhr.onreadystatechange = () => { if (xhr.readyState === 4) { const result = JSON.parse(xhr.response); console.log(result); } } } } |
We are also handling the function on onreadystatechange
to receive the response of the rest API.
6. Output
Let’s combine all code together and see how it looks.
App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import React from 'react'; import 'react-dropzone-uploader/dist/styles.css'; import Dropzone from 'react-dropzone-uploader'; // preview component const Preview = ({ meta }) => { const { name, percent, status, previewUrl } = meta; return ( <div className="preview-box"> <img src={previewUrl} /> <span className="name">{name}</span> - <span className="status">{status}</span>{status !== "done" && <span className="percent"> ({Math.round(percent)}%)</span>} </div> ) } function App() { // specify upload params and API url to file upload const getUploadParams = ({ file }) => { const body = new FormData(); body.append('dataFiles', file); return { url: 'http://localhost:4000/uploadmultifile', body } } // handle the status of the file upload const handleChangeStatus = ({ xhr }) => { if (xhr) { xhr.onreadystatechange = () => { if (xhr.readyState === 4) { const result = JSON.parse(xhr.response); console.log(result); } } } } return ( <div className="App"> <h3>Drag and Drop file upload - <a href="https://www.cluemediator.com" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3> <div> <Dropzone getUploadParams={getUploadParams} onChangeStatus={handleChangeStatus} styles={{ dropzone: { overflow: 'auto', border: '1px solid #999', background: '#f5f5f5' }, inputLabelWithFiles: { margin: '20px 3%' } }} canRemove={false} PreviewComponent={Preview} accept="image/*,audio/*,video/*" /> </div> </div> ); } export default App; |
That’s it for today.
Thank you for reading. Happy Coding..!!
Awesome