> For the complete documentation index, see [llms.txt](https://choubey.gitbook.io/react-coding-puzzles/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://choubey.gitbook.io/react-coding-puzzles/17-drag-and-drop-feature-for-rearranging-items.md).

# 17 - Drag-and-Drop Feature for Rearranging Items

### **Description**

Create a React application that displays an ordered list of items and allows users to drag and drop to change the order. The application should visually indicate the drag state and drop target.

### **Algorithm**

1. Create a state variable to store the list of items.
2. Define a function to handle the drag start event.
3. Define a function to handle the drag over event.
4. Define a function to handle the drop event.
5. Update the state variable when the user drops an item.
6. Render the list of items with a drag handle and a drop target indicator.

### **Classes**

* `DraggableItem`: A component that represents a single item in the list.
* `DraggableList`: A component that renders the list of items and handles the drag and drop events.

### **Code**

DraggableItem.js

```javascript
import React from 'react';

function DraggableItem({ item, onDragStart, onDragOver, onDrop }) {
  return (
    <div>
      <div
        draggable="true"
        onDragStart={onDragStart}
        onDragOver={onDragOver}
        onDrop={onDrop}
      >
        {item.name}
      </div>
      <div className="drag-handle" />
    </div>
  );
}

export default DraggableItem;

```

DraggableList.js

```
import React, { useState } from 'react';
import DraggableItem from './DraggableItem';

function DraggableList() {
  const [items, setItems] = useState([
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' },
  ]);
  const [dragging, setDragging] = useState(null);

  const handleDragStart = (item) => {
    setDragging(item);
  };

  const handleDragOver = (item) => {
    // Update the drop target indicator
    const dropTarget = event.target.closest('.draggable-item');
    if (dropTarget) {
      dropTarget.classList.add('drop-target');
    }
  };

  const handleDrop = (item) => {
    // Update the list of items
    setItems(
      items.map((item1) =>
        (item.id === item1.id ? item1 : dragging)
      )
    );
    // Reset the currently dragging item
    setDragging(null);
  };

  return (
    <div>
      {items.map((item) => (
        <DraggableItem
          key={item.id}
          item={item}
          onDragStart={handleDragStart}
          onDragOver={handleDragOver}
          onDrop={handleDrop}
        />
      ))}
    </div>
  );
}

export default DraggableList;
```

index.css

```css
.draggable-item {
  padding: 10px;
  border: 1px solid #ccc;
  background-color: #fff;
  cursor: move;
}

.drag-handle {
  font-size: 16px;
  cursor: move;
}

.drop-target {
  background-color: #ccc;
}
```

### **Explanation**

The `DraggableItem` component represents a single item in the list and handles the drag start, drag over, and drop events. The `DraggableList` component renders the list of items and handles the drag and drop events. The component uses the `useState` hook to store the list of items and the currently dragging item. The component updates the list of items when the user drops an item.

### Possible Future Enhancements

* Add more features to the drag and drop functionality (e.g., sorting, grouping).
* Use a more advanced drag and drop library (e.g., React DnD).
* Display a placeholder item during the drag operation.
