The whole problem started with some issues I was facing when trying to use Cloudinary file Uploader. After spending a few hours trying to get the setup working, which I did not, I decided to build my own custom image file uploader for the project I am working on.
At first, I had no idea how to implement this, but I knew I would figure it out somehow. (Isn't that what most developers do? 😀)
This project is a React project using Next.js with TypeScript. You might want to spin up a Next.js project to follow along, with a couple of libraries from npm to get the ball rollingâš¾.
Let's create a React component called UploadImageFiles
(Oops, I'm not good at naming stuff, so bear with me 😋). Here is the barebones of the component with some state we will be needing:
Just to move this further, I like to break down my thought process of the implementation into a list. You can call it a pseudocode. 🤷
- Handle user file selection
- Validate the file
- Display the file list (I call this staging 🎬)
Let’s handle the file selection with the help of TypeScript so that we won’t go broke. 😄
The handleFileChange()
function helps with file selection and validates the files for valid file type and the image file size we are expecting. If not, the fileError state will be set. If our checks all pass, then we push the file into the validatedFiles array. The last part of the code sets the selectedFiles state using the setSelectedFiles action with the validatedFiles list.
🚫🚫🚫 Where is FileUpload?
Here you go:
With the file selection and validation out of the way, let’s do some staging…🎬
To add new files to the staging area, our staging function is going to be in a useEffect so that new files are added when selected.
In the staging area, we need the image URL, name, and size. We use the URL to display the image. Since our selectedFiles
is just a list of images, we map through it and return the properties we need (as mentioned above) from it as an object. URL.createObjectURL()
helps to create the image URL. createObjectURL().
The second part of the staging function is setting a distinct image, ensuring no duplicate image file is added to the staging area.
Do not forget to add the
selectedFiles
to theuseEffect
dependency array.
We might need to remove some files from the staging area. The method is quick and short:
You might be wondering, where is our drag ‘n drop logic. Just a moment…
React dropzone provides us with the useDropzone
hook to perform our drag-and-drop feature. From the hook, we destructure the properties we need. You can check out their official documentation for more info: react-dropzone.
We will be making some updates to our handleFileChange
function by moving part of it into a processFiles
function:
One last couple of changes before closing. Add getRootProps
and getInputProps
to the root element and input element respectively:
Here is my current version of the implementation.
Hope you had much fun as I do. Feel free to implement your own features.