Open In App

Building a Drag and Drop Interface with React Hooks

Last Updated : 26 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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 various web applications for tasks like organizing lists, sorting elements, or managing content.

Output Preview: Let us have a look at how the final feature will look like.

final-output

Final Project Output

Approach to create Drag and Drop Interface

We have two box and we are using useState hook to store the current state data of the box. Items are defined as a draggable and this items can be dragged from one box to another box through by using onDragStart, onDragOver and onDrop events. The main functionalities include:

  • Dragging items from one box to another.
  • Preventing the addition of duplicate items in the same box.
  • Dynamically updating the state to reflect changes in each box.

Steps to Create Drag and Drop Feature using React Hooks

Step 1: Create a React application using the following command:

npx create-react-app gfg

Step 2: After creating your project folder(i.e. gfg), move to it by using the following command:

cd gfg

Step 3: Write the code mentioned in the example in App.js and App.css file respectively

Example: This below example demonstrate the Drag and Drop Interface with React Hooks

Javascript




//File path: src/App.js
import React, { useState } from 'react';
import './App.css';
 
const App = () => {
    // State for items in Box 1
    const [box1Items, setBox1Items] = useState([
        { id: 1, text: 'Item 1' },
        { id: 2, text: 'Item 2' },
        { id: 3, text: 'Item 3' },
        { id: 4, text: 'Item 4' },
        { id: 5, text: 'Item 5' }
    ]);
 
    // State for items in Box 2
    const [box2Items, setBox2Items] = useState([]);
 
    // Function to handle the start of a drag operation
    const handleDragStart = (e, item) => {
        // Set the data being dragged as
        //  text/plain with the serialized item
        e.dataTransfer
            .setData('text/plain', JSON.stringify(item));
    };
 
    // Function to handle the drag over event
    const handleDragOver = (e) => {
        // Prevent the default behavior to allow dropping
        e.preventDefault();
    };
 
    // Function to handle the drop event
    const handleDrop = (e, targetBox) => {
        // Prevent the default behavior
        // to avoid unwanted behavior
        e.preventDefault();
 
        // Parse the dropped item from the dataTransfer
        const droppedItem = JSON.parse(
            e.dataTransfer
                .getData('text/plain')
        );
 
        // Check the target box and
        // update the state accordingly
        if (targetBox === 'box1') {
            // Check if the same item is already present in Box 1
            let isSameItemPresent = box1Items.some(
                item => item.id === droppedItem.id
                    && item.text === droppedItem.text
            );
 
            // Update the state of Box 1
            // and remove the item from Box 2
            setBox1Items((prevItems) =>
                //If the same item is already present in Box 1 then
                //again don't add that item
                // else add the new item in Box 1
                isSameItemPresent ?
                    [...prevItems] :
                    [...prevItems, droppedItem]
            );
            setBox2Items((prevItems) =>
                //Remove the dragged item from Box 2
                prevItems.filter(
                    (item) =>
                        item.id !== droppedItem.id
                )
            );
        } else if (targetBox === 'box2') {
            // Check if the same item is already present in Box 2
            let isSameItemPresent = box2Items.some(
                item => item.id === droppedItem.id
                    && item.text === droppedItem.text
            );
 
            // Update the state of Box 2 and remove the item from Box 1
            setBox2Items((prevItems) =>
                //If the same item is already
                // present in Box 2 then
                //again don't add that item
                // else add the new item in Box 2
                isSameItemPresent ?
                    [...prevItems] :
                    [...prevItems, droppedItem]
            );
            setBox1Items((prevItems) =>
                //Remove the dragged item from Box 1
                prevItems.filter(
                    (item) =>
                        item.id !== droppedItem.id
                )
            );
        }
    };
 
    return (
        <>
            <h1>
                Drag and Drop Example
                | GeeksForGeeks
            </h1>
            <div className="container" >
                <div
                    className="box"
                    onDragOver={(e) => handleDragOver(e)}
                    onDrop={(e) => handleDrop(e, 'box1')}>
                    <h3>Box 1</h3>
                    <ul>
                        {box1Items.map((item) => (
                            <li
                                key={item.id}
                                draggable
                                onDragStart={
                                    (e) =>
                                        handleDragStart(e, item)
                                }>
                                {item.text}
                            </li>
                        ))}
                    </ul>
                </div>
                <div
                    className="box"
                    onDragOver={(e) => handleDragOver(e)}
                    onDrop={(e) => handleDrop(e, 'box2')}>
                    <h3>Box 2</h3>
                    <ul>
                        {
                            box2Items.map((item) => (
                                <li
                                    key={item.id}
                                    draggable
                                    onDragStart={
                                        (e) =>
                                            handleDragStart(e, item)
                                    }>
                                    {item.text}
                                </li>
                            ))
                        }
                    </ul>
                </div>
            </div>
        </>
    );
};
 
export default App;


CSS




/* App.css */
 
/* Styling for container */
.container {
    display: flex;
    justify-content: center;
}
 
/* Styling for heading */
h1 {
    text-align: center;
    color: green;
}
 
 
/* Styling for Boxes */
.box {
    border: 2px solid #333;
    padding: 10px;
    margin: 10px;
    width: 250px;
    height: 300px;
}
 
/* Styling for List Items */
ul {
    list-style-type: none;
    padding: 0;
}
 
li {
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    padding: 8px;
    margin: 5px;
    cursor: pointer;
}
 
li:hover {
    background-color: #e0e0e0;
}


To run the application use the following command:

npm run start 

Output: Now go to http://localhost:3000 in your browser:

Drag-Drop-Output

Output



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads