All questions

Sortable List

Premium

Sortable List

Build a vertical list of tasks that the user can reorder by dragging, using the browser's native HTML5 drag-and-drop — no library. The starter App.tsx renders five task rows, each with a grip handle and draggable="true", but nothing moves yet. Your job is to wire the drag events so a row can be dropped into a new position.

What you'll build

Make the list reorderable:

  1. Hold the order in state. Keep the tasks in useState so a reorder is a state update, not a DOM shuffle.
  2. Track the drag. Remember which row started dragging (dragIndex) and which row is currently under the cursor (overIndex, for the drop indicator).
  3. Allow the drop. On dragOver, call e.preventDefault() — without it the browser refuses the drop and onDrop never fires.
  4. Move on drop. Splice the dragged task out of the array and splice it back in at the target index, then setItems with the new order.
  5. Show feedback. The dragged row dims (dragging class) and the hovered row gets a green edge (over class).

Examples

  • Drag Review PR up onto Write tests: on drop, Review PR lands at the top and everything else shifts down.
  • While dragging, the picked-up row fades to 40% opacity and the row you hover shows a green border — a live drop target.
  • Let go outside the list (or press Escape): dragEnd clears the state and nothing moves.

Notes

  • preventDefault on dragOver is mandatory. It is the single most common bug here — skip it and drops silently do nothing.
  • Order lives in state, not the DOM. Reorder the array and let React re-render; never reparent <li> nodes by hand.
  • Native DnD, not pointer math. You are wiring dragStart / dragOver / drop / dragEnd, not computing coordinates.

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium