Drag and Drop File Upload Component with React Hooks
Last Updated :
28 Apr, 2025
In this article, we're going to delve into creating a drag-and-drop feature for uploading files using React Hooks. Dragging and dropping makes it simple for users to add files to a web app. With React Hooks we can control state and execute actions in components simplifying the management of drag and drop functions. By the conclusion of this guide, you'll have an operational drag-and-drop file upload component ready for integration, into your React projects.
Output Preview: Let us have a look at how the final output will look like.
Final outputPrerequisites
Approach to build drag and drop File Upload Component:
- Utilize drop features with HTML5 drag and drop events
- Manage file selection and upload by leveraging the FileReader API along, with AJAX requests.
- Show previews of files using the File API. Incorporate design elements and visual cues to improve user interaction.
Steps to Create the Application:
Step 1: Create a new project by following command
npx create-react-app drag-drop
Step 2: Navigate to the root directory of your project.
cd drag-drop
Folder Structure:
StructureExample: Make two files titled Drop-file-input.css and DropFileInput.jsx and place them in a new directory called components in the source folder.
CSS
/* drop-file-input.css */
.drop-file-input {
position: relative;
width: 800px;
height: 400px;
border: 4px solid var(--border-color);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--input-bg);
}
.drop-file-input input {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
.drop-file-input:hover,
.drop-file-input.dragover {
opacity: 0.6;
}
.drop-file-input__label {
text-align: center;
color: var(--txt-second-color);
font-weight: 600;
padding: 10px;
}
.drop-file-input__label img {
width: 100px;
}
.drop-file-preview {
margin-top: 30px;
}
.drop-file-preview p {
font-weight: 500;
}
.drop-file-preview__title {
margin-bottom: 20px;
}
.drop-file-preview__item {
position: relative;
display: flex;
margin-bottom: 10px;
background-color: var(--input-bg);
padding: 15px;
border-radius: 20px;
}
.drop-file-preview__item img {
width: 50px;
margin-right: 20px;
}
.drop-file-preview__item__info {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.drop-file-preview__item__del {
background-color: var(--box-bg);
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
box-shadow: var(--box-shadow);
cursor: pointer;
opacity: 0;
transition: opacity 0.3s ease;
}
.drop-file-preview__item:hover .drop-file-preview__item__del {
opacity: 1;
}
CSS
/* App.css */
@import url("https://fonts.googleapis.com/css2?family=Monospace:wght@300;400;500;600&display=swap");
:root {
--body-bg: #f5f8ff;
--box-bg: #fff;
--input-bg: #f5f8ff;
--txt-color: #2f2d2f;
--txt-second-color: #ccc;
--border-color: #31c503;
--box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: "Monospace", sans-serif;
font-weight: 400;
line-height: 1.5;
background-color: var(--body-bg);
color: var(--txt-color);
display: flex;
justify-content: center;
padding-top: 100px;
height: 100vh;
}
.box {
background-color: var(--box-bg);
padding: 30px;
border-radius: 20px;
box-shadow: var(--box-shadow);
}
.header {
margin-bottom: 30px;
text-align: center;
}
JavaScript
//App.js
import './App.css';
import DropFileInput from './components/drop-file-input/DropFileInput.js';
function App() {
const onFileChange = (files) => {
console.log(files);
}
return (
<div className="box">
<h2 className="header">
React drop files input
</h2>
<DropFileInput
onFileChange={(files) => onFileChange(files)}
/>
</div>
);
}
export default App;
JavaScript
// ImageConfig.js
export const ImageConfig = {
default: "https://media.geeksforgeeks.org/wp-content/uploads/20240307210250/file-blank-solid-240.png",
pdf: "https://media.geeksforgeeks.org/wp-content/uploads/20240307210251/file-pdf-solid-240.png",
png:"https://media.geeksforgeeks.org/wp-content/uploads/20240307210251/file-png-solid-240.png",
css: "https://media.geeksforgeeks.org/wp-content/uploads/20240307210251/file-css-solid-240.png"
}
JavaScript
// DropFileInput.jsx
import React, { useRef, useState } from 'react';
import PropTypes from 'prop-types';
import './drop-file-input.css';
import { ImageConfig } from '../../config/ImageConfig.js';
const DropFileInput = props => {
const wrapperRef = useRef(null);
const [fileList, setFileList] = useState([]);
const onDragEnter = () => wrapperRef.current.classList.add('dragover');
const onDragLeave = () => wrapperRef.current.classList.remove('dragover');
const onDrop = () => wrapperRef.current.classList.remove('dragover');
const onFileDrop = (e) => {
const newFile = e.target.files[0];
if (newFile) {
const updatedList = [...fileList, newFile];
setFileList(updatedList);
props.onFileChange(updatedList);
}
}
const fileRemove = (file) => {
const updatedList = [...fileList];
updatedList.splice(fileList.indexOf(file), 1);
setFileList(updatedList);
props.onFileChange(updatedList);
}
return (
<>
<div
ref={wrapperRef}
className="drop-file-input"
onDragEnter={onDragEnter}
onDragLeave={onDragLeave}
onDrop={onDrop}
>
<div className="drop-file-input__label">
<img src={"https://media.geeksforgeeks.org/wp-content/uploads/20240308113922/Drag-.png"}
alt="" />
<p>Drag & Drop your files here</p>
</div>
<input type="file" value="" onChange={onFileDrop} />
</div>
{
fileList.length > 0 ? (
<div className="drop-file-preview">
<p className="drop-file-preview__title">
Ready to upload
</p>
{
fileList.map((item, index) => (
<div key={index} className="drop-file-preview__item">
<img src={ImageConfig[item.type.split('/')[1]] ||
ImageConfig['default']} alt="" />
<div className="drop-file-preview__item__info">
<p>{item.name}</p>
<p>{item.size}B</p>
</div>
<span className="drop-file-preview__item__del"
onClick={() => fileRemove(item)}>
x
</span>
</div>
))
}
</div>
) : null
}
</>
);
}
DropFileInput.propTypes = {
onFileChange: PropTypes.func
}
export default DropFileInput;
Start your application using the following command.
npm start
Output:
Drag and Drop File Upload Component with React Hooks
Similar Reads
Implement Drag and Drop using React Component To add drag and drop functionality in your React application, you can use libraries like "react-beautiful-dnd" or "react-dnd". These libraries provide components and hooks that simplify the process of creating draggable and droppable elements in your UI. By wrapping your draggable items with the app
4 min read
ReactJS UI Ant Design Upload Component The Ant Design Upload Component is used to upload files such as images, documents, or any other type of file. It provides various features, such as drag-and-drop support, progress tracking, and customizable upload lists.Syntax: <Upload action="/https/www.geeksforgeeks.org/upload" listType="picture"> <Button icon={<
4 min read
Building a Drag and Drop Interface with React Hooks Drag and Drop Interface feature is a simple React application that demonstrates the drag-and-drop functionality between two boxes. The boxes represent containers and items within them can be dragged and dropped from one box to another. This interactive and user-friendly feature is commonly used in v
4 min read
How to add Draggable Components in Next.js ? In this article, we are going to learn how we can add Draggable Components in NextJs. NextJS is a React-based framework. It has the power to Develop beautiful Web applications for different platforms like Windows, Linux, and mac. The linking of dynamic paths helps in rendering your NextJS components
2 min read
React Single File Upload with Multer and Express.js When we want to add functionality for uploading or deleting files, file storage becomes crucial, whether it's for website or personal use. The File Storage project using Express aims to develop a web application that provides users with a secure and efficient way to store and manage their files onli
5 min read
Sortable Drag and Drop with React and Tailwind CSS In this tutorial, we'll learn how to create a sortable drag-and-drop feature in a React application using Vite for quick and efficient development, along with Tailwind CSS for styling. This feature allows users to reorder items in a list by dragging and dropping them, enhancing the user experience o
3 min read
Drag and Drop Sortable List Using ReactJS Building a drag and drop sortable list in ReactJS allows users to rearrange items interactively by dragging and dropping. This feature enhances the user experience by providing dynamic way to manage lists or items. In this article, weâll explore how to implement a drag and drop sortable list in Reac
4 min read
How to Create a Upload File Button in ReactJS? File upload button is a commen feature in React Apps used to take the file input from user and process it. To perform this we can simple use input type file and trigger the input event with the help of upload button.ApproachTo create a upload file button in React we will be using the input type file
3 min read
How to wait for a ReactJS component to finish updating ? To wait for a ReactJS component to finish updating, we use a loading state in our react application by use of the conditional rendering of the component. ApproachThis can be achieved by the use of the useState and useEffect hooks in the functional components. With the help of the state, we make sure
2 min read
EasyUI React Droppable Component In this article, we will learn how to design a draggable widget using jQuery EasyUI. EasyUI is an HTML5 framework for using user interface components based on jQuery, React, Angular, and Vue technologies. It helps in building features for interactive web and mobile applications saving a lot of time
2 min read