Make a Component Draggable in React

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.

Component Draggable in React
  • 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-draggable

or if you’re using Yarn:

yarn add react-draggable

Step 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.

Draggable Component in React

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:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.