DEV Community

kelseyroche
kelseyroche

Posted on

3

A Beginner’s Guide to Drag-and-Drop with DnD Kit in React

Drag-and-drop functionality can enhance user interactions by allowing elements to be moved dynamically within a UI. In this guide, we'll explore how to implement drag-and-drop using DnD Kit, a lightweight and flexible React library.

🏗 Why Use DnD Kit?

DnD Kit offers:

✅ A modern, unopinionated API for drag-and-drop.

Lightweight (smaller than alternatives like react-beautiful-dnd).

Keyboard support for accessibility.

Customizable sensors (mouse, touch, and keyboard).

Let's dive into the setup and implementation!


🚀 Setting Up DnD Kit

First, install DnD Kit:

npm install @dnd-kit/core

or with Yarn:

yarn add @dnd-kit/core

🛠 Basic Drag-and-Drop Example

We’ll create a simple example where users can drag and drop items between two lists.

1️⃣ Setting Up the Context

In DnD Kit, we wrap our app with a DndContext, which manages drag-and-drop events.


import React, { useState } from "react";
import { DndContext } from "@dnd-kit/core";

function App() {
  const [items, setItems] = useState(["Item 1", "Item 2", "Item 3"]);

  return (
    <DndContext>
      <div>
        {items.map((item, index) => (
          <div key={index}>{item}</div>
        ))}
      </div>
    </DndContext>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

At this stage, nothing is draggable yet. Next, we’ll make the items draggable.

2️⃣ Making Items Draggable

To make items draggable, we use useDraggable from @dnd-kit/core.


import { useDraggable } from "@dnd-kit/core";

function DraggableItem({ id, children }) {
  const { attributes, listeners, setNodeRef, transform } = useDraggable({
    id,
  });

  const style = {
    transform: transform ? `translate(${transform.x}px, ${transform.y}px)` : undefined,
  };

  return (
    <div ref={setNodeRef} {...listeners} {...attributes} style={style}>
      {children}
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Then, update App.js to use DraggableItem:


<DndContext>
  {items.map((item, index) => (
    <DraggableItem key={index} id={index}>
      {item}
    </DraggableItem>
  ))}
</DndContext>

Enter fullscreen mode Exit fullscreen mode

Now, items can be dragged but not yet dropped!

3️⃣ Enabling Droppable Areas

To allow items to be dropped, use the useDroppable hook:


import { useDroppable } from "@dnd-kit/core";

function DroppableArea({ id, children }) {
  const { setNodeRef } = useDroppable({ id });

  return (
    <div ref={setNodeRef} style={{ padding: 20, border: "2px dashed #ccc" }}>
      {children}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Wrap DraggableItem inside DroppableArea:

<DndContext>
  <DroppableArea id="drop-zone">
    {items.map((item, index) => (
      <DraggableItem key={index} id={index}>
        {item}
      </DraggableItem>
    ))}
  </DroppableArea>
</DndContext>

Enter fullscreen mode Exit fullscreen mode

4️⃣ Handling Drag Events

To update state when an item is dropped, use onDragEnd inside DndContext:

function App() {
  const [items, setItems] = useState(["Item 1", "Item 2", "Item 3"]);

  function handleDragEnd(event) {
    const { active, over } = event;
    if (over && active.id !== over.id) {
      setItems((prev) => {
        const updatedItems = [...prev];
        const [movedItem] = updatedItems.splice(active.id, 1);
        updatedItems.splice(over.id, 0, movedItem);
        return updatedItems;
      });
    }
  }

  return (
    <DndContext onDragEnd={handleDragEnd}>
      <DroppableArea id="drop-zone">
        {items.map((item, index) => (
          <DraggableItem key={index} id={index}>
            {item}
          </DraggableItem>
        ))}
      </DroppableArea>
    </DndContext>
  );
}

Enter fullscreen mode Exit fullscreen mode

Now, when an item is dropped, the list updates dynamically! 🎉

🎨 Styling the Drag Effect

To enhance the UI, apply styles:

.draggable {
  padding: 10px;
  margin: 5px;
  background: #f4f4f4;
  border-radius: 5px;
  cursor: grab;
}

Enter fullscreen mode Exit fullscreen mode

🔥 Advanced Features to Explore

• Sorting Lists → @dnd-kit/sortable
• Drag Constraints → Limit draggable areas
• Custom Animations → Smooth transitions
• Keyboard Accessibility → Improve usability
Enter fullscreen mode Exit fullscreen mode




🏁 Wrapping Up

DnD Kit is a lightweight, flexible solution for adding drag-and-drop to React apps. By using DndContext, useDraggable, and useDroppable, you can create interactive and accessible interfaces with minimal effort.

🚀 Try it out in your next project!

💬 Have questions? Drop a comment below!

💡 If you found this helpful, share it and follow me for more React content! 🚀

Neon image

Set up a Neon project in seconds and connect from a Next.js application ⚡

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

Top comments (0)

Neon image

Next.js applications: Set up a Neon project in seconds

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

👋 Kindness is contagious

Value this insightful article and join the thriving DEV Community. Developers of every skill level are encouraged to contribute and expand our collective knowledge.

A simple “thank you” can uplift someone’s spirits. Leave your appreciation in the comments!

On DEV, exchanging expertise lightens our path and reinforces our bonds. Enjoyed the read? A quick note of thanks to the author means a lot.

Okay