complete guide to React Drag-and-Drop Image Preview with Dropzone.js
Tags: react, dropzonejs, javascript, webdev
Published: 2023-04-02 14:05:50

As a web developer, creating a user-friendly interface is key to keeping visitors engaged and satisfied. One feature that has exploded in popularity in recent years is the ability to drag and drop files onto an upload field. Not only does this make uploading files a breeze, but it also creates a seamless user experience that keeps people coming back for more.

Enter DropzoneJS, the ultimate solution for implementing drag and drop file uploads with image previews. Whether you're a beginner or a seasoned pro, DropzoneJS is easy to use, customizable, and supports a wide range of file types. In this article, we'll walk you through how to implement this powerful JavaScript library in React, so you can create a truly engaging online experience. So let's dive in and see how DropzoneJS can take your web development skills to the next level!

**Prerequisites**

- Basic knowledge of React.js
- Familiarity with HTML, CSS, and JavaScript

**Step 1: Setting up the Project**
The first step is to create a new React project or use an existing one. You can use the create-react-app CLI tool to create a new project by running the following command in your terminal:

```
npx create-react-app dropzone-demo

```
**Step 2: Installing Dropzone.js**
Next, You need to install Dropzone.js using npm. Run the following command in your terminal:

```
npm install --save react-dropzone
```
or

```
yarn add react-dropzone
```
**Step 3: Creating a Dropzone Component**
To use Dropzone.js with React, we need to create a new component that will serve as our dropzone. Here's a basic implementation of a Dropzone component:

```js
import React, { useCallback } from "react";
import { useDropzone } from "react-dropzone";

const DropzoneComponent = () => {
  const onDrop = useCallback((acceptedFiles) => {
    console.log(acceptedFiles);
  }, []);

  const { getRootProps, getInputProps } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <p>Drag and drop your files here, or click to select files</p>
    </div>
  );
};

export default DropzoneComponent;
```

In this component, we import useDropzone and useCallback hooks from React. We also define an onDrop function that will handle the files dropped into the dropzone. We then use the useDropzone hook from Dropzone.js to get the necessary props for our dropzone. The getRootProps function returns an object with properties that we can spread onto our dropzone container element, while the getInputProps function returns an object with properties that we can spread onto our input element.

**Step 4: Adding Image Preview**
To add image preview functionality, we can use the FileReader API to read the file and convert it to a data URL, which can then be used as the source for an image tag. Here's an updated implementation of our Dropzone component with image preview:

```js
import React, { useCallback, useState } from "react";
import { useDropzone } from "react-dropzone";

const DropzoneComponent = () => {
  const [files, setFiles] = useState([]);
  const onDrop = useCallback((acceptedFiles) => {
    setFiles(
      acceptedFiles.map((file) =>
        Object.assign(file, {
          preview: URL.createObjectURL(file),
        })
      )
    );
  }, []);

  const { getRootProps, getInputProps } = useDropzone({ onDrop });

  const fileList = files.map((file) => (
    <li key={file.name}>
      <img src={file.preview} alt={file.name} />
      <span>{file.name}</span>
    </li>
  ));

  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <p>Drag and drop your files here, or click to select files</p>
      <ul>{fileList}</ul>
    </div>
  );
};

export default DropzoneComponent;

```
In this updated implementation, we use the useState hook to maintain a list of files that have been dropped into the dropzone. We then update the onDrop function to read each file and create a preview URL using the URL.createObjectURL method. Finally, we use the files list to render an unordered list of images with their names.

**Step 5: Styling the Dropzone**
By default, Dropzone.js provides a basic style for the dropzone container. However, you can customize the style to match your application's design. You can either use CSS to style the dropzone or use Dropzone.js options to customize the appearance. For example, you can set the accepted file types, the maximum file size, and the maximum number of files allowed.

Here's an example of how to set some options in our Dropzone component and some basic styling for your DropZone component:

```js
import React, { useCallback, useState } from "react";
import { useDropzone } from "react-dropzone";

const dropzoneStyle = {
  flex: 1,
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  justifyContent: "center",
  padding: "20px",
  marginTop: "2rem",
  borderWidth: "2px",
  borderRadius: "2px",
  borderColor: "#eeeeee",
  borderStyle: "dashed",
  backgroundColor: "#fafafa",
  color: "#bdbdbd",
  outline: "none",
  transition: "border 0.24s ease-in-out",
  cursor: "pointer",
};

const activeDropzoneStyle = {
  borderColor: "#00adb5",
};

const DropzoneText = {
  margin: "0",
  fontSize: "16px",
  fontWeight: "600",
  textAlign: "center",
};

const ImagePreview = {
  display: "flex",
  maxWidth: "100%",
  maxHeight: "100%",
  margin: "auto",
  borderRadius: "2px",
};

const FileName = {
  display: "flex",
  fontSize: "14px",
  marginTop: "8px",
};

const DropzoneComponent = () => {
  const [files, setFiles] = useState([]);
  const onDrop = useCallback((acceptedFiles) => {
    setFiles(
      acceptedFiles.map((file) =>
        Object.assign(file, {
          preview: URL.createObjectURL(file),
        })
      )
    );
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: "image/*",
    maxSize: 1024 * 1024 * 5,
    maxFiles: 3,
  });

  const fileList = files.map((file) => (
    <li key={file.name}>
      <img style={ImagePreview} src={file.preview} alt={file.name} />
      <span style={FileName}>{file.name}</span>
    </li>
  ));

  return (
    <div
      style={
        isDragActive
          ? { ...dropzoneStyle, ...activeDropzoneStyle }
          : dropzoneStyle
      }
      {...getRootProps()}
    >
      <input {...getInputProps()} />
      <p style={DropzoneText}>
        Drag and drop your files here, or click to select files
      </p>
      <ul>{fileList}</ul>
    </div>
  );
};

export default DropzoneComponent;
```

In this example, we set the accept option to "image/*" to only allow image files to be dropped into the dropzone. We also set the maxSize option to 5MB and the maxFiles option to 3 to limit the size and number of files that can be uploaded. Finally, we added a "dropzone" class to the dropzone container to apply custom styling using CSS.

Conclusion
In this article, you have learnt you how to implement Drag and Drop with Image Preview using Dropzone.js with React. We covered the basic steps of setting up a new React project, installing Dropzone.js, creating a Dropzone component, and adding image preview and custom styling. You can further customize your dropzone by exploring more options and functionality provided by Dropzone.js. Happy coding🎉!
image credits