Simplifying React File Uploads with dex-react-file-upload hook: A Step-by-Step Guide
Introduction
In today's digital era, file uploads have become an integral part of web development, enabling users to share and store various types of data. However, handling file uploads can be challenging, especially when it comes to managing file size, type validation, and processing. Fortunately, dex-react-file-upload is here to simplify the process. In this blog post, we will explore how you can leverage this library to streamline file uploads in your web applications.
Installation
To get started, you'll need to install dex-react-file-upload.
yarn add dex-react-file-upload
Configuring the library
Before diving into file upload functionality, it's essential to configure the library according to your application's requirements. This includes specifying the maximum file size, allowed file types, and the maximum number of accepted files.
Below are all the interfaces this library exposes you can customize to suit your use case.
import { toast } from 'react-toastify';
import { useUploadFile } from 'dex-react-file-upload';
const { fileData, handleChange, handleOnDrop, setFiles } = useUploadFile({
handleError(props: any) {
toast.warn(props?.error?.message);
},
maxFile: 4,
fileType: ['image/jpeg', 'image/jpg', 'image/png'],
multiple: true,
maxfileSize: 2000, //2mb
});
Creating an Upload Form Component
Next, you'll need to create a reusable component that handles the upload for you and also takes care of the native input styling.
Create a file called ImageDropZone.tsx and add this line of code below, I am using tailwind for styling here so you can change to your preferred style it should work the same way.
import { IBlobReturnType } from 'dex-react-file-upload/dist/components/types/types';
import Image from 'next/image';
import { BsTrash } from 'react-icons/bs';
import { handleDeleteFileImage } from '@shared/functions/utils';
import { Dispatch } from 'react';
interface IUpload {
isEmpty: boolean;
handleChange: any;
handleDropImage: any;
inputName: string;
fileData: IBlobReturnType;
setFiles: React.SetStateAction<Dispatch<any>>;
}
export default function ImageZone(props: IUpload) {
return (
<div
data-type={props.inputName}
onDrop={props.handleDropImage}
onDragOver={(event) => event.preventDefault()}
onClick={(e: any) => e.currentTarget.children[0].click()}
className="container cursor-pointer relative mt-7 overflow-x-hidden rounded-md lg:px-2 flex-col border border-dashed h-[20rem] flex justify-center overflow-y-auto"
>
<input
accept="image/png, image/jpeg, image/jpg"
name={props.inputName}
onChange={props.handleChange}
type="file"
className="hidden mt-20 cursor-pointer"
/>
<>
{props.isEmpty ? (
<>
<div className="w-[6rem] h-[6rem] mx-auto mt-10">
<Image
src="/assets/images/upload-image.svg"
alt="uplaod"
layout="responsive"
height="100%"
width="100%"
/>
</div>
<h1 className="mt-4 font-bold text-center lg:text-xl text-primary">
Upload Image of your car
</h1>
<p className="text-sm text-center text-secondary">
Drag and drop or{' '}
<span className="text-accent-1">Select file</span> from your
computer (2MB Max)
</p>
</>
) : (
<div className="grid h-full grid-cols-2 gap-4 pt-4">
{props.fileData?.[props.inputName]?.map((item, idx) => (
<div key={idx + 'eeddh'}>
<div className="relative w-full min-h-[13rem] h-full overflow-hidden bg-white border border-gray-100 rounded-lg ">
<Image
src={item.blob}
objectFit="contain"
layout="fill"
alt="preview"
/>
</div>
</div>
))}
</div>
)}
</>
</div>
);
}
You now have a reusable component you can use anywhere in your application to handle the upload.
Things to note: Even if you don't specify the accept property on the input form the library still catches an error for you provided you added your validations.
Now let's show how to consume this component you just created.
Go back to the file you want to use this component, import the created component and pass the appropriate props and then you are good to go.
import { toast } from 'react-toastify';
import { useUploadFile } from 'dex-react-file-upload';
function App(){
const { fileData, handleChange, handleOnDrop, setFiles } = useUploadFile({
handleError(props: any) {
toast.warn(props?.error?.message);
},
maxFile: 4,
fileType: ['image/jpeg', 'image/jpg', 'image/png'],
multiple: true,
maxfileSize: 2000, //2mb
});
return(
<ImageZone
setFiles={setFiles}
handleDropImage={handleOnDrop}
fileData={fileData}
handleChange={handleChange}
inputName="any-name"
isEmpty={
!fileData?.any-name || fileData?.any-name?.length === 0
}
/>
)
}
Great! You now have a fully functional file uploader that allows users to conveniently drag and drop files, while also providing robust error handling.
Conclusion
Handling file uploads can be complex, but with dex-react-file-upload, the process becomes more manageable and efficient. By following the step outlined in this blog post, you can simplify file upload functionality in your web applications. Leverage the power of dex-react-file-upload to validate file types, manage file size limits, and process uploads seamlessly, providing a smooth user experience.
You can do well to check out the library here: Dex-React-File-upload and if you find it useful please give the project a star on Github
Happy coding!