Working on a dashboard project for a logistics client in the U.S., I needed to make certain widgets draggable. I wanted users to move charts and cards around, just like rearranging items on a whiteboard.
At first, I thought React would have a built-in way to make components draggable. But, as I quickly found out, it doesn’t, we need to use either native HTML drag events or a library like react-draggable.
In this tutorial, I’ll show you two simple methods I personally use to make components draggable in React. The first one uses pure React (no libraries), and the second one uses the react-draggable package, which is perfect for production-level apps.
Method 1 – Make a Component Draggable Using Pure React (No Library)
When I first needed a draggable card, I didn’t want to install any extra packages. So, I built a simple draggable component using React’s built-in state and mouse events.
Here’s the complete code:
import React, { useState } from "react";
function DraggableCard() {
const [position, setPosition] = useState({ x: 0, y: 0 });
const [dragging, setDragging] = useState(false);
const [offset, setOffset] = useState({ x: 0, y: 0 });
const handleMouseDown = (e) => {
setDragging(true);
setOffset({
x: e.clientX - position.x,
y: e.clientY - position.y,
});
};
const handleMouseMove = (e) => {
if (dragging) {
const newX = e.clientX - offset.x;
const newY = e.clientY - offset.y;
setPosition({ x: newX, y: newY });
}
};
const handleMouseUp = () => {
setDragging(false);
};
return (
<div
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
style={{
position: "absolute",
left: position.x,
top: position.y,
width: "200px",
height: "120px",
backgroundColor: "#007bff",
color: "#fff",
borderRadius: "8px",
cursor: "grab",
display: "flex",
alignItems: "center",
justifyContent: "center",
userSelect: "none",
}}
>
Drag Me Around
</div>
);
}
export default DraggableCard;You can see the output in the screenshot below.

- I first set up a state to track the card’s position (x and y).
- When the user presses the mouse button (onMouseDown), I record the offset between the cursor and the element’s position.
- As the mouse moves (onMouseMove), I update the position dynamically.
- Finally, when the mouse is released (onMouseUp), I stop the dragging.
This approach works great for small projects or prototypes.
However, it can get tricky when you have multiple draggable components or want touch support.
That’s where a library can make your life easier.
Method 2 – Use the react-draggable Library
When I started working on a more complex project, I switched to the react-draggable library. It’s lightweight, reliable, and works perfectly with React’s virtual DOM.
Here’s how you can use it.
Step 1 – Install the Package
Open your terminal and run:
npm install react-draggableor if you’re using Yarn:
yarn add react-draggableStep 2 – Create a Draggable Component
import React from "react";
import Draggable from "react-draggable";
function DashboardWidget() {
return (
<Draggable>
<div
style={{
width: "250px",
height: "150px",
backgroundColor: "#28a745",
color: "#fff",
borderRadius: "8px",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: "move",
boxShadow: "0 4px 8px rgba(0,0,0,0.1)",
}}
>
Draggable Dashboard Widget
</div>
</Draggable>
);
}
export default DashboardWidget;Step 3 – Add It to Your App
import React from "react";
import DashboardWidget from "./DashboardWidget";
function App() {
return (
<div style={{ height: "100vh", backgroundColor: "#f8f9fa" }}>
<h2 style={{ textAlign: "center", paddingTop: "20px" }}>
My React Draggable Dashboard
</h2>
<DashboardWidget />
</div>
);
}
export default App;- It supports both mouse and touch events out of the box.
- You can easily restrict movement along the X or Y axis.
- It works well for multiple draggable components.
For example, if you only want to drag horizontally:
<Draggable axis="x">
<div>Drag me sideways!</div>
</Draggable>Or if you want to restrict dragging within a specific area:
<Draggable bounds="parent">
<div>Drag me inside my parent!</div>
</Draggable>You can see the output in the screenshot below.

Bonus Tip – Save the Position in Local Storage
In real-world apps, users like their layouts to “remember” positions. You can easily store the draggable position in local storage so that it persists even after a page refresh.
Here’s a quick example:
import React, { useState, useEffect } from "react";
import Draggable from "react-draggable";
function PersistentWidget() {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const savedPosition = JSON.parse(localStorage.getItem("widgetPosition"));
if (savedPosition) setPosition(savedPosition);
}, []);
const handleStop = (e, data) => {
const newPosition = { x: data.x, y: data.y };
setPosition(newPosition);
localStorage.setItem("widgetPosition", JSON.stringify(newPosition));
};
return (
<Draggable position={position} onStop={handleStop}>
<div
style={{
width: "200px",
height: "120px",
backgroundColor: "#17a2b8",
color: "#fff",
borderRadius: "8px",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: "move",
}}
>
Persistent Widget
</div>
</Draggable>
);
}
export default PersistentWidget;Now, even if you refresh the page, your component will stay where you last left it. This is especially useful for dashboards or drag-and-drop interfaces.
Common Use Cases in U.S. Projects
From my experience working with U.S.-based clients, draggable components are often used in:
- Dashboard layouts (e.g., analytics or logistics panels)
- Custom form builders (dragging input fields into position)
- Interactive maps (moving location markers)
- E-commerce product configurators (adjusting product parts visually)
If you’re building any of these, using react-draggable can save you hours of manual coding.
Both methods, the pure React approach and the react-draggable library, work great depending on your project’s needs. If you want something lightweight and custom, go with the first method. If you need scalability, touch support, and constraints, react-draggable is the smarter choice.
You may also like to read:
- Pass Parameters to Components in React
- Build a Dynamic Star Rating Component in React
- How to Use a React Time Picker Component
- How to Import SVG as a React Component

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.