useDropzone: custom hook that creates a dropzone in your react application!

Steve Kim
3 min readAug 8, 2021
Photo by ANIRUDH on Unsplash

In this post, I would like to share my own custom hook that turns a DOM element into a dropzone where visitors can submit their file into your react application. The hook is less than 100 lines of code. It is very tiny and works fast.

Before you read this post, I assume you are familiar with how react.useEffect and custom hook work in general because detailed explanation regarding them is not provided.

It is a custom hook, not a component.

The images below are a kind of dropzones that the hook can create. It is a custom hook, which only provides minimal logic. It is up to you how to make it stylish and how the accepted file is handled.

simple-dropzone1

Live at https://component-test.vercel.app/simple-dropzone1

simple-dropzone2

Live at https://component-test.vercel.app/simple-dropzone2

The brief on useDropzone.tsx

useDropzone.ts

The hook has 4 states and 1 functions, all of which are returned.

The hook takes a string parameter, {_componentId}. The same value should be assigned to the target component as an id. Then, the component with the id is turned into a dropzone like a normal human turns into a zombie.

As the dropzoned component with the hook renders, each “useEffect” adds three event listeners to the DOM Element with id, {_componentId}. The event listeners are all related to “drag and drop” activities such as “dragover”, “dragleave”, and “drop” to the component.

As a file dragged over to the dropzone, the dndStatus state changes from “none” to “dragover”. As the file dragged out of the dropzone without being dropped, the dndStatus changes from “dragover” to “dragleave”. If the file is finally droped on the dropzone component, the dndStatus becomes “drop” and the hook starts reading the file.

As the file is dropped, information about the file such as the file’s name, size and content are fetched and stored in the states the fileName, fileSize and fileContent. This is all the hook is for. How to deal with the fileName, fileSize and fileContent is up to you.

You may want to upload the fileContent to AWS S3 or display file on <img /> or <video /> tag directly. You can prevent a file greater than certain size on the client side, using fileSize state. Similarly, you can prevent certain type of file from being uploaded, using fileName that includes the file’s extension.

initializeStates() function initializes all the states. It should be called after finishing handling one file to get ready for another file.

The brief on SimpleDropzone.tsx

simple-dropzone1.tsx

SimpleDropzone is a simple example of using useDropzone(). useDropzone() within SimpleDropzone takes “DNDtargetElement” as its unique parameter, and the second <div/> component has its id the same as the parameter. This will make the <div id=“DNDTargetElement” … /> component to be the dropzone.

As the component renders, the event listners are added to the component. Then everything is set. Every time a file is dropped to the component, the hook fetches the file’s information. After dealing with the the file, initializeStates() is executed and gets ready to accept another file.

Ending…

There are really nice 3rd-party module for drag-and-drop. I have used them for a long time and even using them now. But sometimes I would rather make my own than helplessly relying on other developers. Everytime I make my own, I get to know more about how things works. The useDropzone() is one of them.

I hope you to enjoy my post. Thank you for reading.

--

--

Steve Kim

A Certified Public Accountant / Hobbyist-programmer-but-dead-serious-specializing JavaScript, ReactJS, NextJS and AWS.