typescriptintermediate

Drag & Drop Sortable List

Reorder list items with native HTML drag and drop events — no external library required.

typescript
import { useState, useRef } from 'react';

export function useSortable<T>(initial: T[]) {
  const [items, setItems] = useState(initial);
  const dragIdx = useRef<number | null>(null);

  const onDragStart = (index: number) => {
    dragIdx.current = index;
  };

  const onDragOver = (e: React.DragEvent, index: number) => {
    e.preventDefault();
    if (dragIdx.current === null || dragIdx.current === index) return;

    setItems((prev) => {
      const next = [...prev];
      const [moved] = next.splice(dragIdx.current!, 1);
      next.splice(index, 0, moved);
      dragIdx.current = index;
      return next;
    });
  };

  const onDragEnd = () => {
    dragIdx.current = null;
  };

  return { items, onDragStart, onDragOver, onDragEnd };
}

Use Cases

  • Task board reordering
  • Playlist management
  • Priority lists

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.