Europe/Warsaw
BlogJanuary 23, 2024

React modern Drag And Drop (DND) 2024

Kacper Siniล‚o
Drag and drop functionality is an excellent method to empower users with the option to effortlessly sort or relocate content. However, while implementing this feature, I've encountered a challenge โ€“ many libraries offering drag and drop capabilities are outdated and lack support for React versions beyond 18. In this article, we will explore the dnd-kit library, which is designed to seamlessly integrate with the latest versions of React. To get started with dnd-kit, install the library:
Bash
npm install @dnd-kit/core
and then install also
Bash
npm install @dnd-kit/sortable
Tsx
// ๐Ÿงฐ Importing tools for drag and drop
import { DndContext } from "@dnd-kit/core";
import {
  arraySwap,
  rectSwappingStrategy,
  SortableContext,
} from "@dnd-kit/sortable";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { useState } from "react";

export default function HomePage() {
  // ๐ŸŽ๐ŸŠ๐Ÿ“ Setting up our collection
  const [items, setItems] = useState([
    "apple",
    "orange",
    "strawberry",
    "banana",
    "grape",
    "kiwi",
    "blueberry",
    "pineapple",
    "watermelon",
  ]);

  // ๐Ÿ”„ Updating positions after dragging
  const handleDragEnd = event => {
    const { active, over } = event;

    if (active.id !== over.id) {
      setItems(items => {
        const oldIndex = items.indexOf(active.id);
        const newIndex = items.indexOf(over.id);

        return arraySwap(items, oldIndex, newIndex); // ๐Ÿš€ We can also use other techniques like arrayMove
      });
    }
  };

  // ๐Ÿž๏ธ Creating a playground for sorting
  return (
    <DndContext onDragEnd={handleDragEnd}>
      <SortableContext items={items} strategy={rectSwappingStrategy}>
        {/* Our collection goes here */}
        <div className="grid max-w-96 grid-cols-3 gap-5">
          {items.map(item => (
            <SortableItem key={item} id={item} value={item} />
          ))}
        </div>
      </SortableContext>
    </DndContext>
  );
}

const SortableItem = props => {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id: props.id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition: transition || undefined,
  };

  return (
    <div
      className={
        "flex size-24 items-center justify-center rounded-lg bg-slate-200"
      }
      ref={setNodeRef}
      style={style}
      {...props}
      {...attributes} // ๐Ÿ–ผ๏ธ These attributes make the image draggable
      {...listeners} // ๐Ÿ”Š These listeners help capture the dragging actions
    >
      <p>{props.value}</p>
    </div>
  );
};
For more information, you can explore the dnd-kit documentation.