How to Implement Drag and Drop Functionality in React: An Easy Guide
Are you looking for a way to add drag-and-drop functionality to your React application? If so, you are in luck. In this article, we'll go over how to implement drag-and-drop using the React library React-dnd.
Let's take a moment to talk about what drag-and-drop is and how it is useful.
Understanding drag and drop in React
When we talk about drag and drop in React, we're talking about a way for users to move things around on a website or app by clicking on them and dragging them to a new location. It's a way of interacting with the content on the screen that feels very intuitive and natural to most people.
For example, In a file manager, drag and drop can be used to allow users to move files between folders or upload them to a website. A user might drag a file from their desktop and drop it into a folder in the file manager to save it there.
React is a popular JavaScript library for building user interfaces, and it provides a way to implement drag-and-drop functionality in your app using frameworks and libraries like react-dnd
, which offers a collection of tools and APIs for managing the various parts of the interaction, and react-dnd-html5-backend
, which enables React DnD.
When using react-dnd, you can specify, for instance, which parts of your app are "drag sources" (items that can be dragged) and which parts are "drop targets" (item-dropping locations). Additionally, you can specify how various objects should behave when they are dropped, such as if they should snap to a particular location.
Installation
npm install react-dnd react-dnd-html5-backend
If you're using yarn
as your package manager, you can install react-dnd
and react-dnd-html5-backend
with the following command:
yarn add react-dnd react-dnd-html5-backend
This will install the latest versions of react-dnd
and react-dnd-html5-backend
and add them to your project's package.json
file.
Note that the yarn add
command is equivalent to npm install
, but it's the command used by the yarn
package manager.
What is React DND?
React-dnd is a library for implementing complex drag-and-drop functionalities in React, and it provides a lower-level solution. It supports mouse and touch events and makes use of the HTML5 drag-and-drop API to provide a set of hooks for creating drag-and-drop interfaces.
There are two main hooks in the library:
useDrag
useDrop
These functions enable drag-and-drop behavior in a React application.
useDrag
The hook useDrag
from react-dnd accepts an object with the following properties:
type
: A string used to identify the type of item being dragged.item
: An object containing data about the item being dragged.collect
: A function that returns an object with information about the dragging state.
useDrag
enables the component to receive dropped items of the specified type, here the type is "todo".
import React, { useRef } from "react";
import { useDrag } from "react-dnd";
const Task = () => {
const [{ isDragging }, drag] = useDrag({
type: "todo",
item: {todo, id: todo.id },
collect: (monitor) => ({isDragging: !!monitor.isDragging(),
})
});
//...
const ref = useRef(null);
return (
<div
draggable
ref={(instance);
ref.current = instance;
}}
>
// ...
</div>
);
};
export default Task;
useDrag
hook returns an array with two items: [{ isDragging }, drag]. The first item is an object with information about the dragging state, and the second item is a function used to attach the drag functionality to the DOM element.
useDrop
The useDrop
hook takes an object as its argument, which defines the properties of the drop, target. These properties include the types of draggable items the target can accept, whether the target is currently, being hovered over by, a draggable item, and functions that should be called when a draggable item is, dropped on the target.
Once the useDrop
hook is applied to a component, that component becomes a drop target that can accept draggable items that match the specified types. When a draggable item is dropped on a target, the functions specified in the object argument are invoked, allowing the component to properly handle the dropped item.
// Import the necessary functions and types from react-dnd
import { useDrop } from 'react-dnd';
function Drop(props) {
// Use the useDrop hook to create a drop target for draggable items
const [{ isOver }, drop] = useDrop({
// Define the types of draggable items that the target can accept
accept: Item,
// Define what should happen when a draggable item is dropped onto the target
drop: (item, monitor) => {
// Do something with the dropped item, such as update the state of the parent component
props.onDrop(item);
},
// Define how the drop target should respond to being hovered over by a draggable item
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
});
return (
<div ref={drop} style={{ backgroundColor: isOver ? 'yellow' : 'white' }}>
{props.children}
</div>
);
}
export default Drop
DnDProvider
<DndProvider>
is a higher-order component (HOC) provided by the react-dnd
library that wraps your entire React application and provides the necessary context and tools for implementing drag-and-drop functionality.
To use <DndProvider>
, you first need to import it from the react-dnd
package:
The <DndProvider>
component takes one prop: backend
, which specifies the drag-and-drop backend to use. In the example below, we used the HTML5Backend
, which is the default backend provided by the react-dnd-html5-backend
package.
By wrapping your application components with <DndProvider>
, you're essentially creating a context where drag and drop can be used. Any component that requires drag-and-drop functionality must be rendered within the context to function correctly, as demonstrated below:
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
fuunction App() {
return (
<div>
<DndProvider backend={HTMLBackend}>
//...
</DndProvider>
</div>
);
}
export default App;
Conclusion
In general, you have learned the fundamental procedures for implementing a drag-and-drop feature using react-dnd.
If you are interested in seeing how drag-and-drop can be used in a real-world project, check out my GitHub repository, where I've integrated this feature. If you like learning about and using React, you might also want to consider following me on GitHub to see more projects and give back to the open-source community.
Reference
I would love to connect with you on Twitter | LinkedIn | GitHub