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

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.

Live at

Live at

The brief on useDropzone.tsx

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

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.


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.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store