React Dropzone and File Uploads in React

React Dropzone and file uploads in React banner showing a cloud file upload image next to the React logo.

In this tutorial, we’ll learn how to use React Dropzone to create an awesome file uploader. Keep reading to learn more about react-dropzone.

To begin, open up an existing React project. If you don’t have an existing React project that uses the react-dropzone library, generate a new one using Create React App. I’ll show you how to do this below.

Call the new project file-upload.

I’m also showing you the option to install Bootstrap, which I’ll be using in the examples throughout this tutorial. 

npx create-react-app file-upload
cd file-upload
npm install --save react-dropzone

// Optional
npm install --save bootstrap jquery popper.js

A Basic React Dropzone File Picker

We’re going to start by building a very simple file picker using React Dropzone.

As an extra challenge, try to follow this tutorial using React Hooks. If you’re knew to Hooks, I’ve written a simple introduction to React Hooks.

Jump into App.js and start by removing the code in the render function. Import Dropzone at the top of the file, below all of the other imports.

Finally, add the React Dropzone component to the return of the render method, as well as an onDrop method above it.

Your App.js should look like this:

import React, { Component } from 'react';
import Dropzone from 'react-dropzone'

class App extends Component {

  onDrop = (acceptedFiles) => {
    console.log(acceptedFiles);
  }

  render() {
    return (
      <div className="text-center mt-5">
        <Dropzone onDrop={this.onDrop}>
          {({getRootProps, getInputProps}) => (
            <div {...getRootProps()}>
              <input {...getInputProps()} />
              Click me to upload a file!
            </div>
          )}
        </Dropzone>
      </div>
    );
  }
}

export default App;

React Dropzone only needs one method passed into the onDrop prop to handle files when they’re selected. We’re naming the method the same as the prop: onDrop.

Our method has a single parameter, acceptedFiles, which we’re logging out to the console.

Save the component, open your browser and go to your React app. Click the text label and a file picker window will open up! We’ve got a basic file picker UI working.

A basic working version of a file picker with React Dropzone.

Clicking a file to upload won’t do anything just yet. For that to work, we have to send the file to a server, which we’ll cover at a later date.

Let’s continue to explore what else React Dropzone can do!

Render Props

Dropzone may look different to other React components because it has a return statement inside of it.

That’s called a Render Prop Function, and it’s used to change the HTML inside of the component, based on the state of Dropzone.

Let’s add another prop called isDragActive so that that we have access to Dropzone’s current drag state.  That will let us change the text of the label to show something different when a file is dragged over the component.

<Dropzone onDrop={this.onDrop}>
  {({getRootProps, getInputProps, isDragActive}) => (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      {isDragActive ? "Drop it like it's hot!" : 'Click me or drag a file to upload!'}
    </div>
  )}
</Dropzone>

In the code above, we’re writing an inline conditional that checks if isDragActive is true. If it is write “Drop it like it’s hot”, else write “Click me or drag a file to upload!”.

Let’s jump back to the browser and see it in action!

Allowing Specific Types of File

Currently, our file picker allows us to pick any type of file to upload.

Depending on what you’re using a file picker for, you may want to allow specific types of files, such as only .JPG files, or only .XLS and .DOCX files.

To do this, we’ll use the accept prop.

Let’s add the accept prop after onDrop within the Dropzone component declaration, like so:

<Dropzone
  onDrop={this.onDrop}
  accept="image/png, image/gif"
>
...
</Dropzone>

File types are written as MIME types, with multiple values separated by a comma. Mozilla has a great resource that gives a full list of MIME types

Let’s improve our file picker user experience by showing a message if the user tries to upload a file type that’s not accepted.

To do that, we’ll add another render prop called isDragRejected. We’ll move around the inline conditional logic somewhat to account for this new render prop.

<Dropzone
  onDrop={this.onDrop}
  accept="image/png"
>
  {({getRootProps, getInputProps, isDragActive, isDragReject}) => (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      {!isDragActive && 'Click here or drop a file to upload!'}
      {isDragActive && !isDragReject && "Drop it like it's hot!"}
      {isDragReject && "File type not accepted, sorry!"}
    </div>
  )}
</Dropzone>

Save the file, hop on back to your browser and try to drag a .JPG file onto the file picker.

A message appears letting the user know that our file picker doesn’t accept that type of file. Perfect!

Minimum and Maximum File Size

Specifying the minimum and maximum file size is very important. In a real world file uploader, you wouldn’t want one of your users dragging in a 1GB file to upload, and crippling your server.

Luckily we can limit the size of the file that’s being uploaded in React Dropzone through two props, minSize and maxSize. Both of these props take a number value specified in bytes.

For your reference, 1 Megabyte = 1048576 Bytes.

Jump back into your code, and add the two minSize and maxSize props to the Dropzone component, right underneath the accept prop.

<Dropzone
  onDrop={this.onDrop}
  accept="image/png"
  minSize={0}
  maxSize={5242880}
>
  ...
</Dropzone>

We’re accepting a file with a maximum size of 5MB and under in the example above.

Let’s add some more code to our file input component that checks the maximum file size and displays an error message if the file being uploaded is larger.

 render() {
    const maxSize = 1048576;
    return (
      <div className="text-center mt-5">
        <Dropzone
          onDrop={this.onDrop}
          accept="image/png"
          minSize={0}
          maxSize={maxSize}
        >
          {({getRootProps, getInputProps, isDragActive, isDragReject, rejectedFiles}) => {
            const isFileTooLarge = rejectedFiles.length > 0 && rejectedFiles[0].size > maxSize;
            return (
              <div {...getRootProps()}>
                <input {...getInputProps()} />
                {!isDragActive && 'Click here or drop a file to upload!'}
                {isDragActive && !isDragReject && "Drop it like it's hot!"}
                {isDragReject && "File type not accepted, sorry!"}
                {isFileTooLarge && (
                  <div className="text-danger mt-2">
                    File is too large.
                  </div>
                )}
              </div>
            )}
          }
        </Dropzone>
      </div>
    );
  }

It might look like we’ve added a lot, but actually it’s less than 10 lines.

  • At the top of the render method, we declare a new const called maxSize and set it to 1MB.
  • Reference this new maxSize variable in the maxSize prop within Dropzone.
  • We add another render prop to Dropzone called rejectedFiles
  • Directly underneath the render prop function within Dropzone, we declare another const called isFileTooLarge, which gets the first file from the rejectedFiles array prop, and checks to see if the size is greater than our maxSize variable.
  • Finally, we’re writing an inline conditional that checks if isFileTooLarge is true, and renders ‘File is too large.’ in red.

Let’s see it in action!

Multiple Files

The last feature of React Dropzone that we’ll cover is the ability to upload multiple files.

This one is fairly simple, as we’re not adding any code inside the render prop function.

Just add the prop multipleto the React Dropzone component declaration, like so:

<Dropzone
  onDrop={this.onDrop}
  accept="image/png"
  minSize={0}
  maxSize={maxSize}
  multiple
>
  ...
</Dropzone>

Wrapping Up

There you have it. A simple file picker built using React Dropzone. If you run into any issues, don’t forget to leave a comment below.


We'll only ever send you our latest tutorials each month, nothing more. Not like those idiots at Wayfair who send you fifty-million emails a day about their latest sale, ugh.


Write a response

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.