Clue Mediator

Drag and Drop File Upload in React using react-dropzone-uploader

šŸ“…May 20, 2020
šŸ—ReactJS

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

  1. Setup react application
  2. Install dropzone package
  3. Integrate dropzone package
  4. Design the preview component
  5. Integrate file upload API
  6. 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.

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.

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.

// 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)
}
</file_upload_api_url>

Use the above functions in dropzone for rendering in the component.

<dropzone getuploadparams={getUploadParams} onchangestatus={handleChangeStatus} accept="image/*, audio/*, video/*">
</dropzone>

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.

<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/*">
</dropzone>

Over here we have customized the preview component and that looks like below.

// preview component
const Preview = ({ meta }) => {
  const { name, percent, status, previewUrl } = meta;
  return (
    <div class="preview-box">
      <img src={previewUrl}> <span class="name">{name}</span> - <span class="status">{status}</span>{status !== "done" && <span class="percent">Ā ({Math.round(percent)}%)</span>}
    </div>
  )
}

index.css

.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.

// 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

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 class="preview-box">
      <img src={previewUrl}> <span class="name">{name}</span> - <span class="status">{status}</span>{status !== "done" && <span class="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 class="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/*">
      </dropzone></div>
    </div>
  );
}

export default App;

Output - Drag and Drop file upload in React using react-dropzone-uploader - Clue Mediator

Output - Drag and Drop file upload in React using react-dropzone-uploader - Clue Mediator

Thatā€™s it for today.
Thank you for reading. Happy Coding..!!

Demo & Source Code

Github Repository StackBlitz Project