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