How to Create Drag and Drop in React: Simple Guide
To create drag and drop in React, use the native HTML5 drag events like
onDragStart, onDragOver, and onDrop on elements. Manage the dragged item state with React hooks to update the UI when an item is dropped.Syntax
Use these key event handlers on draggable elements:
draggable="true": Makes an element draggable.onDragStart: Fires when dragging starts; use to store dragged data.onDragOver: Fires when a dragged item is over a drop target; callevent.preventDefault()to allow dropping.onDrop: Fires when the dragged item is dropped; use to update state or perform actions.
jsx
function DragDropSyntax() { const handleDragStart = (event) => { event.dataTransfer.setData('text/plain', event.target.id); }; const handleDragOver = (event) => { event.preventDefault(); // Allow drop }; const handleDrop = (event) => { event.preventDefault(); const data = event.dataTransfer.getData('text/plain'); console.log('Dropped item id:', data); }; return ( <div> <div id="drag-item" draggable={true} onDragStart={handleDragStart}> Drag me </div> <div onDragOver={handleDragOver} onDrop={handleDrop} style={{width: '200px', height: '100px', border: '1px solid black', marginTop: '10px'}}> Drop here </div> </div> ); }
Output
A draggable box labeled 'Drag me' and a drop area labeled 'Drop here'. Dragging the box and dropping it logs the dragged item's id in the console.
Example
This example shows a list of items you can drag and reorder by dropping them in a new position. It uses React hooks to track the dragged item and update the list order.
jsx
import React, { useState } from 'react'; export default function DragAndDropList() { const [items, setItems] = useState(['Apple', 'Banana', 'Cherry']); const [draggedIndex, setDraggedIndex] = useState(null); const handleDragStart = (index) => { setDraggedIndex(index); }; const handleDragOver = (event) => { event.preventDefault(); }; const handleDrop = (index) => { if (draggedIndex === null) return; const newItems = [...items]; const draggedItem = newItems.splice(draggedIndex, 1)[0]; newItems.splice(index, 0, draggedItem); setItems(newItems); setDraggedIndex(null); }; return ( <ul style={{width: '150px', padding: 0}}> {items.map((item, index) => ( <li key={item} draggable={true} onDragStart={() => handleDragStart(index)} onDragOver={handleDragOver} onDrop={() => handleDrop(index)} style={{ listStyle: 'none', padding: '8px', margin: '4px 0', border: '1px solid #ccc', cursor: 'grab', backgroundColor: '#f9f9f9' }} aria-grabbed={draggedIndex === index} tabIndex={0} > {item} </li> ))} </ul> ); }
Output
A vertical list of three items: Apple, Banana, Cherry. You can drag any item and drop it on another to reorder the list instantly.
Common Pitfalls
Common mistakes when creating drag and drop in React include:
- Not calling
event.preventDefault()inonDragOver, which blocks dropping. - Not setting
draggable="true"on draggable elements. - Using indexes directly without stable keys, causing unexpected behavior.
- Not managing drag state properly, leading to incorrect drop results.
Always test keyboard accessibility and screen reader announcements for better accessibility.
jsx
/* Wrong: Missing preventDefault in onDragOver blocks drop */ function WrongDrop() { const handleDrop = (e) => { alert('Dropped!'); }; return <div onDragOver={() => {}} onDrop={handleDrop} style={{width: 100, height: 100, border: '1px solid'}}> Drop here </div>; } /* Right: preventDefault allows drop */ function RightDrop() { const handleDrop = (e) => { alert('Dropped!'); }; const handleDragOver = (e) => { e.preventDefault(); }; return <div onDragOver={handleDragOver} onDrop={handleDrop} style={{width: 100, height: 100, border: '1px solid'}}> Drop here </div>; }
Quick Reference
Remember these key points for React drag and drop:
- Set
draggable="true"on elements you want to drag. - Use
onDragStartto save dragged data or index. - Call
event.preventDefault()inonDragOverto allow dropping. - Use
onDropto handle the drop and update state. - Manage drag state with React hooks for smooth UI updates.
- Test accessibility: keyboard and screen reader support.
Key Takeaways
Use native HTML5 drag events with React hooks to create drag and drop.
Always call event.preventDefault() in onDragOver to enable dropping.
Manage dragged item state to update UI correctly after drop.
Set draggable="true" on elements to make them draggable.
Test drag and drop for accessibility and keyboard navigation.