Have you ever wanted to let users reorder items in a list by dragging and dropping them? That’s exactly what we’ll build using React DnD – a powerful and flexible drag-and-drop library designed for React.
In this tutorial, you’ll learn:
-
What React DnD is
-
How to install and configure it
-
How to build a reorderable list
-
How to manage drag state using
react-dnd
Let’s get started building an interactive drag-and-drop list!
📦 Step 1: Set Up Your React Project
If you don’t have a project yet, create one:
npx create-react-app react-dnd-list
cd react-dnd-list
npm install react-dnd react-dnd-html5-backend
npm start
Dependencies installed:
-
react-dnd
: Main drag-and-drop logic -
react-dnd-html5-backend
: Enables HTML5 drag-and-drop in browsers -
⚙️ Step 2: Create a Basic List
In
src/App.js
, set up a basic UI:import React, { useState } from "react"; const initialItems = [ { id: 1, text: "Item One" }, { id: 2, text: "Item Two" }, { id: 3, text: "Item Three" }, { id: 4, text: "Item Four" }, ]; function App() { const [items, setItems] = useState(initialItems); return ( <div className="App"> <h2>Drag and Drop List</h2> {items.map((item, index) => ( <div key={item.id} style={{ padding: "10px", border: "1px solid #ccc", margin: "5px" }}> {item.text} </div> ))} </div> ); } export default App;
This shows a static list. Next, we will make it draggable.
🏗️ Step 3: Wrap Your App with DnD Provider
In
index.js
, wrap your app withDndProvider
: -
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; ReactDOM.render( <React.StrictMode> <DndProvider backend={HTML5Backend}> <App /> </DndProvider> </React.StrictMode>, document.getElementById("root") );
-
🧱 Step 4: Create the Draggable Item Component
Let’s separate the list item into a component:
DraggableItem.js
. -
// DraggableItem.js import React, { useRef } from "react"; import { useDrag, useDrop } from "react-dnd"; const ItemType = "ITEM"; function DraggableItem({ item, index, moveItem }) { const ref = useRef(null); const [, drop] = useDrop({ accept: ItemType, hover(draggedItem) { if (draggedItem.index === index) return; moveItem(draggedItem.index, index); draggedItem.index = index; }, }); const [, drag] = useDrag({ type: ItemType, item: { index }, }); drag(drop(ref)); return ( <div ref={ref} style={{ padding: "10px", margin: "5px", border: "1px solid #ccc", backgroundColor: "#f0f0f0", cursor: "move", }} > {item.text} </div> ); } export default DraggableItem;
-
🔍 Explanation:
-
useDrag()
: Marks this item as draggable. -
useDrop()
: Makes it a valid drop target. -
drag(drop(ref))
: Connects both refs to the DOM node.
🔁 Step 5: Manage Item Reordering in App.js
Update your
App.js
to useDraggableItem
and reorder items: -
-
import React, { useState } from "react"; import DraggableItem from "./DraggableItem"; const initialItems = [ { id: 1, text: "Item One" }, { id: 2, text: "Item Two" }, { id: 3, text: "Item Three" }, { id: 4, text: "Item Four" }, ]; function App() { const [items, setItems] = useState(initialItems); const moveItem = (fromIndex, toIndex) => { const updatedItems = [...items]; const [movedItem] = updatedItems.splice(fromIndex, 1); updatedItems.splice(toIndex, 0, movedItem); setItems(updatedItems); }; return ( <div className="App" style={{ width: "300px", margin: "50px auto" }}> <h2>React DnD - Drag and Drop List</h2> {items.map((item, index) => ( <DraggableItem key={item.id} index={index} item={item} moveItem={moveItem} /> ))} </div> ); } export default App;
-
Step 6: Add CSS for Better UX
Update
index.css
with a cleaner style:body { font-family: Arial, sans-serif; background-color: #f8f9fa; } .App { text-align: center; } h2 { color: #333; }
-
📚 Summary of Concepts Used
Concept Description react-dnd
The main DnD library for React. react-dnd-html5-backend
Enables DnD in the browser. useDrag
Makes an item draggable. useDrop
Allows other items to accept the dragged item. drag(drop(ref))
Combines drag and drop refs on the same element. moveItem()
Handles item swapping logic in the state array.
💡 Bonus: Improve UX (Optional)
Add styles to highlight the drag or drop states:
-
Change background color on hover.
-
Use animations while reordering.
-
Add a delete button to remove items.
🎉 Conclusion
You’ve now built a functional drag-and-drop list using React DnD! This type of feature is commonly used in:
-
Task management apps (like Trello)
-
Sorting lists
-
Kanban boards
-
Custom dashboards
By understanding
useDrag
anduseDrop
, you gain powerful control over interactive UIs in React.Keep exploring more with:
-
Nested drag-and-drop
-
Dragging between lists
-
Drop zones with conditions
-