React Dropzone Uploader

Kyle Bebak
Fortana
Published in
4 min readMar 13, 2019

Building a file uploader is hard.

Just uploading the file to your server or S3 can be tricky enough. When you start adding features like drag and drop, file previews with image thumbnails, upload progress and cancellation, and upload status and error handling, you realize you shouldn’t be doing it from scratch.

I was in this situation on a recent project. I looked for ready-made solutions to the problem and found there weren’t any with the features I mentioned, at least not any that made it easy to customize the look and feel. So I went down the rabbit hole and built React Dropzone Uploader.

RDU takes the feature sets of older uploader libraries such as Dropzone.js and merges them into a modern, fully customizable file dropzone and uploader, with a minimal API and sensible defaults. It tries to make the easy things easy and the hard things possible.

Here’s some of what it does:

  • Detailed file metadata and previews, especially for image, video and audio files
  • Upload status and progress, upload cancellation and restart
  • Easily set auth headers and additional upload fields (see S3 examples)
  • Customize styles using CSS or JS
  • Take full control of rendering with component injection
  • Take control of upload lifecycle
  • Modular design; use as standalone dropzone, file input, or file uploader
  • Cross-browser support, mobile friendly, lightweight (13kb minzipped)

And here’s the code you’d have to write:

To get a feel for just how easy it is to use RDU, check out the live, editable examples.

Existing Dropzone Libraries

React already has dropzone/uploader libraries, which begs the question: is RDU really necessary?

Some comparisons are in order. First, with libraries that offer both a dropzone and upload management. Two of the most popular are react-fine-uploader and React-Dropzone-Component. Why not use them?

  1. They weren’t really built for React. They’re wrappers around fine-uploader and Dropzone.js, file uploaders with sprawling APIs that weren’t designed with React in mind. Both weigh many times more than RDU.
  2. They’re not maintained. The react-fine-uploader and fine-uploader repos were shut down in 2018. React-Dropzone-Component hasn’t seen a commit to source code since 2017; pretty much ditto with Dropzone.js.

React Dropzone

There’s also the popular and solid react-dropzone, but this library only gives you a dropzone — it has no API for managing uploads.

Again, file uploads (with previews, status, progress, cancellation, restart, etc) are hard to get right. They’re also the most common use case for a dropzone, so I thought it made sense to build a library that gives you both.

I also wanted a friendlier rendering API and better rendering defaults. react-dropzone doesn’t help you with rendering:

1. It doesn’t provide file previews. You have to write them yourself, which means lots of boilerplate for even basic previews.
2. It doesn’t provide default styles. This makes no difference if you style everything yourself, but I wanted a component, like React Select, that looks good and works well out of the box, and makes it trivial to override individual styles.
3. It actually renders nothing by default. To render anything you have to pass a render prop as a child of Dropzone. This means understanding getRootProps, getInputProps, and isDragActive, and writing 10+ lines of boilerplate.

RDU abstracts away things like getRootProps and getInputProps, which for most cases are implementation details. Of course it lets you access them and take full control of rendering using the component injection API if you want.

RDU vs React Dropzone

Here’s a comparison of RDU and React Dropzone for implementing a dropzone that uploads files to https://httpbin.org/post:

react-dropzone-uploader: uploads files, and removes them if upload is successful.

react-dropzone (code mostly taken from React Dropzone’s docs):

Uploads files, and removes them if upload is successful. Doesn’t handle upload failure. Previews have no upload progress. No active state on drag over. No reject state if dragged files have incorrect file types. Behaves incorrectly if user drags a second group of files before first group has finished uploading (bonus points if you can spot why this happens).

10 lines of code that are production ready, vs 100 that aren’t even close.

Contributing

Because of the way RDU is built, anyone can create new Layout, Preview, Input or SubmitButton components (which might be a lot prettier than the defaults) without touching RDU’s code.

I’d love to see a curated collection of RDU components, so developers could put together a Facebook or Dropbox or Google Drive uploader without writing any code. I welcome PRs to add these components to RDU’s GitHub repo, or to link to them in other repos.

If building a file uploader was getting you down, I hope this post helped. And I hope it got you interested in component injection if you hadn’t seen that pattern before.

Most of all, I hope you try RDU in your project. It’ll save you time, and it just might help you build something better than you expected.

Kyle Bebak is Co-Founder of Fortana, a software consultancy that works with startups from Y Combinator, Stanford, Harvard, and other top programs. They focus on strategy, design, and full-stack engineering in React, React Native, and Django.

--

--

Kyle Bebak
Fortana
Editor for

Web developer that lives between California and Mexico City. I enjoy reading, coding, writing, biking, and walking my dog.