Overview
In this exercise, you will create a simple React drag and drop functionality without using any external libraries. You will implement this functionality by creating two containers, one for draggable items and the other for dropped items.
Instructions for React Drag and Drop
- Create two container components, one for the draggable items and one for the dropped items.
- Create a few draggable items within the first container. These can be simple divs with some text inside.
- Then Implement drag and drop functionality by adding
onDragStart
,onDragOver
,onDragEnter
, andonDrop
event handlers to the draggable and droppable components. - When the user starts dragging an item, set the item’s id as the
dataTransfer
object’s data. - When a draggable item is being dragged over the droppable container, prevent the default behavior by calling
event.preventDefault()
and change the background color of the droppable container to indicate that it is a valid drop target. - When dropped, move the item from the draggable to the dropped container.
- Finally, update the state of the parent component to reflect the changes in the items’ containers.
Bonus Requirements
- Add animation effects to the drag and drop functionality.
- Then Implement the functionality to allow the user to drag and drop items between multiple containers.
- Add the ability to delete items from the dropped container.
- Use local storage to persist the state of the containers, ensuring the state remains on page refresh.
Take time to complete the exercise before viewing the final output. I believe that active learning is the most effective way to learn and grow as a developer.
Prepare your tools and start the React Drag and Drop exercise. Once you have completed the exercise, feel free to return to this blog post to compare your solution to mine.
Output for the Drag and Drop exercise
import React, { useState } from 'react';
import { DraggableContainer, DroppedContainer } from './containers';
import './styles.css';
function App() {
const [availableItems, setAvailableItems] = useState([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
{ id: 4, name: 'Item 4' },
{ id: 5, name: 'Item 5' },
]);
const [droppedItems, setDroppedItems] = useState([]);
const handleDragStart = (event, item) => {
event.dataTransfer.setData('text/plain', JSON.stringify(item));
};
const handleDragOver = (event) => {
event.preventDefault();
};
const handleDrop = (event) => {
event.preventDefault();
const data = JSON.parse(event.dataTransfer.getData('text/plain'));
if (!droppedItems.find((item) => item.id === data.id)) {
setDroppedItems([...droppedItems, data]);
}
};
const handleRemoveItem = (item) => {
setDroppedItems(droppedItems.filter((i) => i.id !== item.id));
};
return (
<div className="app-container">
<DraggableContainer items={availableItems} onDragStart={handleDragStart} />
<DroppedContainer
items={droppedItems}
onDragOver={handleDragOver}
onDrop={handleDrop}
onRemoveItem={handleRemoveItem}
/>
</div>
);
}
export default App;
import React from 'react';
function DraggableContainer(props) {
return (
<div className="draggable-container">
{props.items.map((item) => (
<div
key={item.id}
className="draggable-item"
draggable="true"
onDragStart={(event) => props.onDragStart(event, item)}
>
{item.name}
</div>
))}
</div>
);
}
function DroppedContainer(props) {
return (
<div
className="dropped-container"
onDragOver={props.onDragOver}
onDrop={props.onDrop}
>
{props.items.map((item) => (
<div key={item.id} className="dropped-item">
{item.name}
</div>
))}
</div>
);
}
export { DraggableContainer, DroppedContainer };
.draggable-container {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
width: 100%;
height: 200px;
border: 1px solid black;
margin-bottom: 20px;
}
.draggable-item {
display: flex;
justify-content: center;
align-items: center;
width: 80px;
height: 80px;
background-color: white;
border: 1px solid black;
border-radius: 5px;
margin-bottom: 10px;
cursor: move;
}
.dropped-container {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
width: 100%;
height: 200px;
border: 1px solid black;
}
.dropped-item {
display: flex;
justify-content: center;
align-items: center;
width: 80px;
height: 80px;
background-color: lightgray;
border: 1px solid black;
border-radius: 5px;
margin-bottom: 10px;
}
Drag and drop is a versatile user interface feature that can be used in many applications to improve the user experience. Here are some examples of applications where drag and drop can be used:
- File Management System: A file management system could allow users to drag and drop files between folders, move files around within a folder, or even drag and drop files onto an external storage device.
- Kanban Boards: A kanban board is a project management tool that allows teams to visualize their work in progress. Use drag and drop to move tasks from one column to another, reorder tasks within a column, or even move tasks between different boards.
- Image Galleries: An image gallery could allow users to drag and drop images to rearrange them or move them into different albums.
- Email Management System: An email management system could allow users to drag and drop emails into folders, move emails around within a folder, or even drag and drop attachments to save them to a local folder.
- Spreadsheet Application: A spreadsheet application could allow users to drag and drop cells to rearrange them or move them to different sheets.
These are just a few examples of how developers use drag and drop in various applications to improve the user experience and make complex tasks more intuitive and efficient.
Additionally, thanks for taking this JavaScript exercise!
I hope you found this exercise helpful and enjoyable, and moreover, that it has deepened your understanding of React development. Additionally, keep practising and experimenting with React, and you’ll be well on your way to becoming a skilled React developer!
Boost your React skills with 25 React JavaScript Practice Exercises with Solutions hands-on challenges to master components, hooks, and more!