dnd-kit i Drag and Drop w React
dnd-kit (useSortable, DndContext), kanban drag między kolumnami, Pragmatic DnD (Atlassian) i DnD w Next.js App Router.
6 bibliotek Drag and Drop dla React
dnd-kit, Pragmatic DnD, react-beautiful-dnd, react-dnd, Framer Motion Reorder i @use-gesture — API, dostępność, wirtualizacja i zastosowanie.
| Biblioteka | API | Dostępność | Virtual | Bundle | Kiedy |
|---|---|---|---|---|---|
| dnd-kit | useSortable, DndContext | Doskonała (keyboard) | Tak | ~26KB | Domyślny wybór 2024, sortable listy, kanban |
| Pragmatic DnD | Low-level, native events | Tak | Tak | ~15KB | Atlassian apps, framework-agnostic, zaawansowane |
| react-beautiful-dnd | Draggable, Droppable | Dobra | Nie | ~30KB | Legacy, migruj do dnd-kit |
| react-dnd | useDrag, useDrop | Słaba | Ograniczone | ~25KB | Legacy, brak nowych projektów |
| Framer Motion Reorder | Reorder.Group/Item | Słaba | Nie | ~50KB | Proste sortowanie z animacją |
| @use-gesture | useDrag, useGesture | Manualna | Manualna | ~10KB | Custom gestures, nie sortable listy |
Często zadawane pytania
Co to jest dnd-kit i dlaczego zastąpił react-beautiful-dnd?
dnd-kit (Claudéric Demers, 2021): nowoczesna biblioteka drag and drop dla React. Modular, lightweight, accessibility-first. TypeScript-first. Nie zależy od DOM order (virtual list support). Brak deprecated API (react-beautiful-dnd używa legacy React API). react-beautiful-dnd (Atlassian): popularna ale wycofywana. Używa wycofanych React API (legacy context). Brak wsparcia dla wirtualizowanych list. Ostatni commit 2022. Atlassian migruje do Pragmatic Drag and Drop. dnd-kit instalacja: npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities. Pakiety: @dnd-kit/core — rdzeń (DndContext, sensors). @dnd-kit/sortable — sortable listy (useSortable). @dnd-kit/modifiers — constrainty (restrictToVerticalAxis). @dnd-kit/utilities — CSS transforms. Podstawowa architektura: DndContext — provider. useDraggable — element który można ciągnąć. useDroppable — miejsce upuszczenia. useSortable — element sortowalny (łączy oba). Sensors: MouseSensor, TouchSensor, KeyboardSensor. PointerSensor — recommended (mouse + touch). useSensor, useSensors. Accessibility: keyboard drag and drop wbudowany. ARIA announcements. Screen reader support. Zero visual focus trap issues.
useSortable i SortableContext — jak sortować listy?
SortableContext: wrapper dla sortowalnych elementów. items prop — tablica id (strings). strategy — algorytm sortowania. import {SortableContext, verticalListSortingStrategy} from '@dnd-kit/sortable'. Strategie: verticalListSortingStrategy — pionowa lista. horizontalListSortingStrategy — pozioma. rectSortingStrategy — siatka (grid). rectSwappingStrategy — zamiana miejscami. useSortable hook: const {attributes, listeners, setNodeRef, transform, transition, isDragging} = useSortable({id: item.id}). setNodeRef — ref na element. attributes — ARIA attributes. listeners — event handlers (onPointerDown etc). transform — CSS transform dla animacji. style: {transform: CSS.Transform.toString(transform), transition}. isDragging — czy aktualnie ciągnięty. DndContext handlers: onDragStart — start przeciągania. onDragOver — nad dropzone. onDragEnd — koniec. arrayMove: import {arrayMove} from '@dnd-kit/sortable'. onDragEnd: ({active, over}) => {if (active.id !== over?.id) {setItems(items => {const oldIndex = items.indexOf(active.id). const newIndex = items.indexOf(over.id). return arrayMove(items, oldIndex, newIndex)})})}. DragOverlay: komponent pokazywany podczas drag. Renderuj kopię elementu. import {DragOverlay} from '@dnd-kit/core'. Ghosting: opacity na isDragging element. Alternatywa: przeniesienie do DragOverlay i ukrycie oryginału.
Kanban Board z dnd-kit — drag między kolumnami?
Kanban drag między kolumnami: każda kolumna to container. Droppable dla kolumn. Elementy mogą być przenoszone między kolumnami. Multi-container pattern: useDroppable na kolumnie. items: {[columnId]: Card[]}. Over prop w onDragOver — nad jakiej kolumnie. onDragOver: move item to target column (optimistically). onDragEnd: finalize position. Implementacja: type Column = {id: string, items: Item[]}. DndContext z onDragOver i onDragEnd. Każda kolumna: DroppableColumn komponent. SortableContext wewnątrz kolumny. items = column.items.map(i => i.id). onDragOver handler: const overId = over?.id. Sprawdź czy over to kolumna czy element. Jeśli element: znajdź jego kolumnę. Przesuń item do nowej kolumny. Aktualizuj state. Sortable między kolumnami: @dnd-kit/sortable SortableContext dla każdej kolumny. Strategy: verticalListSortingStrategy. Multi-container SortableContext. Przykłady: Trello-like board. Project management. Task management (Asana). Wirtualizacja z dnd-kit: @tanstack/react-virtual + dnd-kit. useSortable z virtualizer. Skomplikowane ale możliwe. Drag handle: drag tylko przez handle. setActivatorNodeRef dla handle elementu. attributes + listeners na handle button. Constrained drag: modifiers: [restrictToVerticalAxis, restrictToParentElement]. Brak wyjścia poza kontener. Drag distance threshold: PointerSensor z activationConstraint: {distance: 8}. Unikaj przypadkowych drag.
Pragmatic Drag and Drop (Atlassian) — nowa generacja DnD?
Pragmatic Drag and Drop (Atlassian, 2024): następca react-beautiful-dnd. Framework-agnostic. Nie używa React API bezpośrednio. Bardzo niskopoziomowy. Doskonała wydajność. Używany w Jira, Confluence, Trello. Instalacja: npm install @atlaskit/pragmatic-drag-and-drop. Adaptory: @atlaskit/pragmatic-drag-and-drop-react-drop-indicator (React). Podejście: native browser drag and drop events. Brak React coupling. Mniejszy bundle niż dnd-kit dla złożonych przypadków. Kiedy dnd-kit: solidna, sprawdzona. Dobra dokumentacja. Sortable listy, kanban. Kiedy Pragmatic DnD: zaawansowane przypadki. Framework-agnostic. Atlassian apps. HTML5 Drag and Drop API (natywne): draggable='true' na elementach. onDragStart, onDragOver, onDrop events. Brak animacji. Brak touch support. Brak wirtualizacji. Proste use-case. react-dnd: starsza biblioteka (v16). Backend pattern (HTML5Backend, TouchBackend). Tightly coupled z React legacy. Brak aktywnego maintenance. use-gesture (@use-gesture/react): gesture library — drag, pinch, scroll, wheel. Nie tylko DnD. Dla custom gesture interactions. Kompatybilna z react-spring, Framer Motion. Brak sortable built-in. Połącz z własną sortable logikę. Dostępność DnD: keyboard navigation. ARIA live regions. Komunikaty o akcjach. dnd-kit — najlepsza dostępność. react-beautiful-dnd — dobra. HTML5 DnD — żadna.
Drag and Drop w Next.js — server components i hydration?
DnD w Next.js App Router: DnD wymaga przeglądarki. DndContext musi być w Client Component. Cały Kanban board: 'use client'. Server Components dla static/data parts. Strategia: Server Component ładuje dane (karty, kolumny). Passes data do Client Component (KanbanBoard). Client Component ma DndContext. Problemy hydration: DnD library zwykle bezpieczna dla hydration. Unikaj window/document w SSR. Sprawdź: typeof window !== 'undefined'. PointerSensor na SSR: brak PointerEvent na serwerze. Lazy initialize sensors. SSR safe pattern: const [mounted, setMounted] = useState(false). useEffect(() => setMounted(true), []). if (!mounted) return Skeleton. Persist state po drag: optimistic updates. Server Action po onDragEnd. useOptimistic z React 19. Bez optimistic: loading state między drag i server response. Zustand persist: drag state w Zustand. Persist do localStorage. Wróć do stanu po odświeżeniu. Uwaga: hydration mismatch jeśli localStorage różni się od SSR. useIsMounted pattern do bezpiecznego init. Framer Motion + DnD: LayoutGroup dla smooth layout transitions. animate={true} na sortable items. layout prop na komponentach. Reorder komponent Framer Motion: import {Reorder} from 'framer-motion'. Reorder.Group — kontener. Reorder.Item — element. Proste sortowanie z animacją. Brak multi-container support. Lepsza animacja niż dnd-kit default. Kombinacja: dnd-kit logic + Framer Motion animation. AnimatePresence dla mount/unmount. Animate item do nowej pozycji.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz