Drag & Drop Sortable List
Reorder list items with native HTML drag and drop events — no external library required.
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.
Virtualized List Component
Render large lists efficiently by only rendering visible items with calculated scroll positioning.
useFetch — Generic Data Fetching Hook
Custom React hook for data fetching with loading, error, and refetch states using the Fetch API.
useDebounce — Debounced Value Hook
Debounce any rapidly-changing value with a configurable delay. Useful for search inputs and resize handlers.
useLocalStorage — Persistent State Hook
Sync React state with localStorage including SSR safety, JSON serialization, and cross-tab updates.