React Draggable Guide: Features, Installation & Examples for Drag & Drop

Creating interactive and intuitive user interfaces is essential for a seamless user experience. One of the common interactions needed is the ability to drag and move elements within a page, such as organizing lists. But how do we add the draggable functionality? The answer is, React draggable.

React draggable provides a solution to this by allowing developers to easily implement drag-and-drop functionality in their websites. In this blog, we’ll dive into how to install and use the react-draggable library. We’ll also learn how ReactJS development experts make use of it to create a site with a draggable list. With that said, let’s begin!

What is React Draggable?

React draggable is a lightweight library for React that enables drag-and-drop functionality for components. It allows users to click and drag elements within a web page, creating more dynamic and interactive user interfaces. Developers can apply this functionality to elements like cards or panels, making them draggable across the screen or within specific boundaries.

By using React draggable, you can:

  • Create resizable elements: Allow users to resize elements to their desired dimensions.
  • Implement custom layouts: Enable users to rearrange elements to create unique layouts.
  • Build interactive components: Develop components that respond to user interactions through dragging and dropping.
  • Enhance user experience: Provide a more simple and engaging interface for your users.

React draggable is a popular choice for professional JavaScript developers due to its flexibility and compatibility with the React ecosystem. It offers various customization options and can be integrated seamlessly into your existing React projects.

Key Features of React Draggable

  • Simple Integration: React draggable is easy to integrate into a React project. By wrapping components with <Draggable> from the library, you can make elements draggable with minimal setup.
  • Axis Locking: React draggable allows you to restrict dragging along a specific axis. You can configure elements to be dragged only horizontally or vertically using the axis prop (“x” for horizontal, “y” for vertical).
  • Boundaries and Constraints: You can set boundaries for where elements can be dragged. The bounds prop helps restrict the drag area, preventing elements from moving beyond a defined region.
  • Event Handling: React draggable provides event listeners, such as onStart, onDrag, and onStop, that allow you to trigger functions during different stages of the drag process. These events give you more control and flexibility over how dragging works.
  • Controlled and Uncontrolled Modes: In uncontrolled mode, React draggable handles the drag state (position) internally, which is useful for simple implementations. Conversely, in controlled mode, you can manage the position of the draggable component via props.
  • Handle and Cancel Props: The handle props allow you to specify a specific area or child element of a component that can be used as the “drag handle”. The cancel props allow you to specify areas where dragging should be disabled, restricting drag initiation on certain parts of the component.
  • Nested Draggables: React draggable supports nested draggable elements. That means you can have draggable components within other draggable components with proper event handling for both parent and child elements.

These features of React draggable make it a powerful tool used by professional React developers to create flexible and interactive interfaces.

Struggling to make your React website interactive?

How to Install React Draggable?

Before we start to know more about using the react-draggable, let’s dive into how can you install the library:

Step 1: If you don’t have an existing React project, you can create a new React using Create-React-App with the following command:

npx create-react-app draggable-playlist

Step 2: Use the cd command to navigate to the newly created project directory. For example:

cd react
// If you created the project in the directory named react

Step 3: Once you’re in the project directory, run the following command in your terminal to install the react-draggable library:

npm install --save react-draggable

This command will download and install the React draggable library along with its dependencies into your project.

By following the above steps, you’ll have React draggable successfully installed in your React project. Now you can import the Draggable component from the library and start creating draggable elements in your React components.

How does React Draggable Work?

React draggable works by wrapping a component within a <Draggable> element, which allows it to be moved by clicking and dragging. Internally it listens to mouse or touch events, calculates the new position of the element as it’s dragged, and repositions the element accordingly. Here’s how React draggable works in more detail:

Initialization

You wrap any element (like a div, img, or custom component) inside a <Draggable> component provided by the react-draggable library. For example:

import Draggable from 'react-draggable';
function MyDraggableComponent() {
  return (
    <Draggable>
      <div className="draggable-box">Drag me!</div>
    </Draggable>
  );
}

In this example, the div becomes draggable, allowing users to move it freely across the screen.

Event Handling

React draggable tracks various events related to dragging such as:

onStart: This event fires when the drag action begins (when the mouse or touch event is first detected). It captures initial information like the starting coordinates or any other data that might be needed. Here is the usage example:

<Draggable
  onStart={(e, data) => console.log('Drag started at position:', data)}
>
  <div>Drag me!</div>
</Draggable>

onDrag: This event is fired continuously as the element is dragged. It allows you to monitor the current position and make adjustments in real-time. You can use this event to track the position or apply custom logic during the drag, such as updating state or applying boundaries. Here is the usage example:

<Draggable
  onDrag={(e, data) => console.log('Dragging at position:', data)}
>
  <div>Drag me!</div>
</Draggable>

onStop: This event is fired when the drag action ends (when the mouse button or touch is released). It captures the final coordinates and can be used for actions like updating the final position or triggering other behaviors after the drag ends. Here is the example usage:

<Draggable
  onStop={(e, data) => console.log('Drag stopped at position:', data)}
>
  <div>Drag me!</div>
</Draggable>

These events provide hooks to execute custom logic during the drag process, such as updating state or triggering other actions. Here’s how you can combine all three event listeners (onStart, onDrag, and onStop) to monitor a draggable component’s lifecycle:

import React from 'react';
import Draggable from 'react-draggable';
function DraggableExample() {
  return (
    <Draggable
      onStart={(e, data) => console.log('Drag Start Position:', data)}
      onDrag={(e, data) => console.log('Dragging at:', data)}
      onStop={(e, data) => console.log('Drag Stop Position:', data)}
    >
      <div className="draggable-box">Drag me!</div>
    </Draggable>
  );
}
export default DraggableExample;

Here, the data argument provides information such as the element’s position (x, y), which can be used for calculations or interactions.

Position Calculation

As the user drags the element, React draggable continuously updates the position of the element based on the mouse or touch movement. It calculates the offset between the starting position (where the drag began) and the current mouse/touch position. The element’s style is updated dynamically with the new transform property, which changes its position on the page:

.draggable-box {
  transform: translate(x, y);
}

Controlled and Uncontrolled Modes

React draggable can function in two modes: uncontrolled and controlled mode. Here is a how they both of them works:

Uncontrolled Mode: In this mode, React draggable handles the internal state of the draggable element. You don’t need to manually track the position; the library manages everything behind the scenes. Here is an example:

<Draggable>
  <div className="draggable-box">Uncontrolled Drag</div>
</Draggable>

Controlled Mode: You can control the position of the draggable component through props, such as position or defaultPosition. This mode gives you more control over the element’s position, allowing synchronization with external logic or UI. Here is an example of controlled mode:

const [position, setPosition] = useState({ x: 0, y: 0 });
return (
  <Draggable
    position={position}
    onDrag={(e, data) => setPosition({ x: data.x, y: data.y })}
  >
    <div className="draggable-box">Controlled Drag</div>
  </Draggable>
);

Axis Locking

You can limit the dragging to only the x-axis (horizontal) or y-axis (vertical) using the axis prop:

<Draggable axis="x">
  <div className="draggable-box">Horizontal Only</div>
</Draggable>

This feature is particularly useful when you need to restrict movement, such as when dragging a slider or resizing elements.

Boundaries

You can define boundaries to prevent the draggable element from moving outside a specific area. The bounds prop can be set to a parent element, or custom values can be specified as coordinates. Here is a example that shows the use of bounds:

<Draggable bounds="parent">
  <div className="draggable-box">Drag within parent</div>
</Draggable>

In this case, the element can only be dragged within the boundaries of its parent container.

Handle and Cancel

In React draggable, handle and cancel are collectively referred to as the “handle and cancel elements”. These elements define the areas within a draggable component that can trigger drag operations or prevent them from starting.

Handle: You can specify a handle, a part of the element that is draggable, while the rest of the element remains static. This is useful for complex interfaces with specific draggable areas (e.g., header bars on modals).

<Draggable handle=".handle">
  <div>
    <div className="handle">Drag me by this handle</div>
    <div>Content here</div>
  </div>
</Draggable>

Cancel: The cancel prop can be used to exclude parts of the element from being draggable. If the user clicks on the excluded part, dragging won’t start.

<Draggable cancel=".no-drag">
  <div>
    <div>Drag me!</div>
    <div className="no-drag">Don't drag me!</div>
  </div>
</Draggable>

Detailed Example of React Draggable in Action

Here’s a complete example of how to use React draggable in action. It will demonstrate key features such as axis locking, boundaries, event handling, and draggable handles.

import React, { useState } from 'react';
import Draggable from 'react-draggable';
import './App.css';
function App() {
  // State for controlled position
  const [controlledPosition, setControlledPosition] = useState({ x: 0, y: 0 });
  // Function to handle controlled drag movement
  const handleControlledDrag = (e, position) => {
    const { x, y } = position;
    setControlledPosition({ x, y });
  };
  // Function to handle controlled drag stop
  const handleControlledStop = (e, position) => {
    console.log('Drag stopped at:', position);
  };
  return (
    <div className="App">
      <h1>React Draggable Example</h1>
      {/* Uncontrolled Draggable */}
      <Draggable>
        <div className="draggable-box">
          Uncontrolled Draggable Box - Drag me freely!
        </div>
      </Draggable>
      {/* Draggable with axis locking (horizontal only) */}
      <Draggable axis="x">
        <div className="draggable-box">
          Horizontal Draggable - Drag me only horizontally!
        </div>
      </Draggable>
      {/* Draggable with boundaries (within parent) */}
      <div className="boundary-container">
        <Draggable bounds="parent">
          <div className="draggable-box">
            Boundaries Draggable - Stay inside this box!
          </div>
        </Draggable>
      </div>
      {/* Draggable with event handling */}
      <Draggable
        onStart={(e, data) => console.log('Drag started at:', data)}
        onDrag={(e, data) => console.log('Dragging at:', data)}
        onStop={(e, data) => console.log('Drag stopped at:', data)}
      >
        <div className="draggable-box">
          Event Handling Draggable - Check the console!
        </div>
      </Draggable>
      {/* Draggable with a handle */}
      <Draggable handle=".handle">
        <div className="draggable-box-with-handle">
          <div className="handle">Drag me by this handle</div>
          <div>But not by this area!</div>
        </div>
      </Draggable>
      {/* Controlled Draggable */}
      <Draggable
        position={controlledPosition}
        onDrag={handleControlledDrag}
        onStop={handleControlledStop}
      >
        <div className="draggable-box">
          Controlled Draggable - Current position: ({controlledPosition.x}, {controlledPosition.y})
        </div>
      </Draggable>
    </div>
  );
}
export default App;

The above examples shows a complete example of using React draggable with various props defined. Now, let’s dive into draggable event listeners and how professional ReactJS development services use them to create interactive sites.

How to Drag a Div in React?

To make a div draggable in React, you can use the react-draggable library. This library provides an easy-to-use Draggable component that wraps the div and allows it to be dragged along the x-axis, y-axis, or both. Here are is stepwise guide to drag a div in react:

Step 1: First, you need to install the react-draggable library. Use the following command:

npm install react-draggable

Step 2: Now, you’ll need to import the Draggable component into your React project using the code:

import Draggable from 'react-draggable';

Step 3: Create a new component that uses the Draggable component from react-draggable to make a div draggable.

import React from 'react';
import Draggable from 'react-draggable';
const DraggableDiv = () => {
  return (
    <Draggable>
      <div style={{ width: 200, height: 200, background: 'lightblue', cursor: 'move' }}>
        Drag me!
      </div>
    </Draggable>
  );
};
export default DraggableDiv;

Step 4: Use the DraggableDiv component in your main application file (e.g., App.js):

import React from 'react';
import DraggableDiv from './DraggableDiv';
const App = () => {
  return (
    <div style={{ height: '100vh', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
      <DraggableDiv />
    </div>
  );
};
export default App;

Step 5: Start your React application to see the draggable div in action:

npm start

With that, we have used the react-draggable library to drag a div in React. Now let’s jump to how expert ReactJS developers implement react-draggable in a real world setting in the next section.

Creating a Draggable List in React

Creating a draggable list in React allows users to reorder items dynamically through drag-and-drop interactions. You can accomplish this by combining the react-draggable library with React’s state management. Below, we will go through the steps to create a simple draggable list.

Step 1: If you haven’t already installed the library, use the following command:

npm install react-draggable

Step 2: Now, you’ll need to create a component that renders a list of items. Each item in the list will be wrapped with the Draggable component.

import React, { useState } from 'react';
import Draggable from 'react-draggable';
const DraggableList = () => {
  const [items, setItems] = useState([
    'Item 1',
    'Item 2',
    'Item 3',
    'Item 4',
    'Item 5',
  ]);
  const handleDrag = (e, data, index) => {
    // Logic to manage drag state or movement can be added here.
    console.log(`Dragging ${items[index]} at x: ${data.x}, y: ${data.y}`);
  };
  const handleStop = (e, data, index) => {
    // Logic to update the item order can be added here.
    // This can be a function to reorder the items based on the dragged index.
    console.log(`${items[index]} dragged to x: ${data.x}, y: ${data.y}`);
  };
  return (
    <div>
      <h2>Draggable List</h2>
      {items.map((item, index) => (
        <Draggable
          key={index}
          onDrag={(e, data) => handleDrag(e, data, index)}
          onStop={(e, data) => handleStop(e, data, index)}
        >
          <div
            style={{
              padding: '10px',
              margin: '5px',
              backgroundColor: 'lightblue',
              cursor: 'move',
            }}
          >
            {item}
          </div>
        </Draggable>
      ))}
    </div>
  );
};
export default DraggableList;

Step 3: To enable reordering, you need to keep track of the position and update the state when the dragging ends. Here’s how you can implement that:

const handleStop = (e, data, index) => {
  const newItems = [...items];
  const draggedItem = newItems.splice(index, 1)[0]; // Remove the dragged item
  const newIndex = Math.round(data.y / 50); // Assuming each item has a height of 50px
  // Insert the dragged item at the new position
  newItems.splice(newIndex, 0, draggedItem);
  setItems(newItems);
};

Step 4: Once you have the logic added, import and render the DraggableList component in your main application file:

import DraggableList from './DraggableList';
function App() {
  return (
    <div>
      <h1>React Draggable List Example</h1>
      <DraggableList />
    </div>
  );
}
export default App;

Step 5: Now, to run the website that we created use the command:

npm start

If the website runs and you are able to drag the list of items, you have created the web application successfully. This was one of the basic examples; if you want to create a site with complex functionality, consider hiring ReactJS developers.

FAQs About Using React Draggable

Can I use React draggable with other libraries?
Yes, React draggable can be easily integrated with other libraries or frameworks. It works well with state management libraries like Redux and context APIs.
How do I make a component draggable?
To make a component draggable, wrap it with the component. You can customize the dragging behavior using various props, such as axis, bounds, and handle.
Can I restrict dragging to a specific area of the site in React?
Yes, you can set boundaries for dragging using the bounds prop to limit the movement of draggable components to a specified area of the website.

Wrapping Up

React draggable is a valuable tool for developers aiming to enhance user experience through simple drag-and-drop functionality. Its features, like customizable drag boundaries and real-time event listeners, enable developers to create dynamic interfaces.

To implement the draggable functionality, you can install the react-draggable library and add various props for further customization. You can make customization like axis locking and boundaries and use modes like controlled and uncontrolled for core logic.

If you want to make a dynamic and interactive website that also performs well, hire ReactJS developers.

Looking to build a robust website with React?

author
Mayur Upadhyay is a tech professional with expertise in Shopify, WordPress, Drupal, Frameworks, jQuery, and more. With a proven track record in web development and eCommerce development.

Leave a comment