React drag and drop: sorteerbare lijst en kanbanbord
Gids voor React drag and drop
React drag and drop: sorteerbare lijst en kanban (dnd-kit) | We.Inc
Bouw een sorteerbare lijst en een kanbanbord in React met dnd-kit, of met de native HTML drag-events. Live bord op de pagina, inclusief verplaatsen met het toetsenbord, kopieerbare code.
Voor de meeste React-apps is dnd-kit de eenvoudigste degelijke keuze: een toolkit onder MIT-licentie met ingebouwde sensoren voor pointer, touch en toetsenbord. Installeer @dnd-kit/react, omhul het gebied met DragDropProvider, geef elke kaart useSortable met een id, index en group, en werk daarna uw state bij in onDragEnd. De native HTML drag-events werken ook, met meer handgeschreven code.
Twee manieren om drag and drop toe te voegen
dnd-kit (@dnd-kit/react)
Native HTML drag and drop
Installatie
npm install @dnd-kit/react
Niets, zit ingebouwd in browsers
Toetsenbord
Toetsenbordsensor inbegrepen
U bouwt uw eigen toetsbediening
Touch
Touch- en pointersensoren inbegrepen
Verschilt per browser; test op telefoons
Sorteerbare lijsten
useSortable uit @dnd-kit/react/sortable
Uw eigen indexberekeningen in drop-handlers
Het beste voor
Kanbanborden, sorteerbare lijsten, grids
Bestanden neerzetten of eenvoudige losse drops
Hieronder staat een werkend bord waarop u nu meteen kaarten kunt slepen, met pijlknoppen voor iedereen die geen muis gebruikt. Daaronder vindt u de dnd-kit-code voor dezelfde sorteerbare lijst en hetzelfde bord met meerdere kolommen, plus de versie met gewone browserevents ter vergelijking.
Sleep een kaart binnen de kolom om de volgorde te wijzigen, of naar een andere kolom om hem te verplaatsen.
Geen muis? Ga met Tab naar een kaart en gebruik de verplaatsknoppen om de positie of kolom te wijzigen.
Kopieer eerst de sorteerbare lijst met dnd-kit, daarna de kanbanversie die per kolom een group toevoegt.
Bewaar de gegevens van uw bord als gewone state per kolom en laat onDragEnd de volgende kopie maken.
Geef elk sleepbaar element een stabiele id uit uw gegevens. Array-indexen als id gaan stuk zodra items verschuiven.
Stop vroegtijdig als event.canceled true is, zodat Escape tijdens het slepen het bord onaangeroerd laat.
Sla de nieuwe volgorde na de drop op in uw backend en draai de wijziging terug als het verzoek mislukt.
Laat een zichtbare ruimte of omlijning zien waar de kaart terechtkomt; mensen moeten het doel zien voordat ze loslaten.
Lege kolommen hebben nog steeds een dropzone met enige hoogte nodig, anders kan er nooit iets in worden neergezet.
Veelgestelde vragen
Is react-beautiful-dnd nog een goede keuze?
Atlassian heeft de repository van react-beautiful-dnd gearchiveerd en raadt de opvolger aan, Pragmatic drag and drop. Voor nieuw React-werk zijn dnd-kit en Pragmatic drag and drop de actief onderhouden opties om te vergelijken.
Wat is het verschil tussen @dnd-kit/core en @dnd-kit/react?
@dnd-kit/core met @dnd-kit/sortable is het React-pakketpaar dat al lang bestaat. @dnd-kit/react is de nieuwere adapter, gebouwd op een framework-onafhankelijke kern die ook de adapters voor Vue, Svelte en Solid aandrijft. Nieuwe code kan beginnen met @dnd-kit/react, zoals de huidige documentatie doet.
Waarom wordt mijn drop-event nooit uitgevoerd met de HTML API?
Een droptarget moet event.preventDefault() aanroepen in de dragover-handler. Zonder die aanroep behandelt de browser het element als een ongeldig doel en wordt het drop-event nooit verstuurd.
Hoe maak ik drag and drop toegankelijk?
Maak elke kaart focusbaar, bied een manier om hem met het toetsenbord op te pakken, te verplaatsen en neer te zetten, en meld het resultaat in een live region. dnd-kit levert direct een toetsenbordsensor en toegankelijkheidsondersteuning mee; met de native API voegt u dat allemaal zelf toe.
Eerst de state, dan het slepen
Een bord is een object met arrays: één array met kaart-id's per kolom. Slepen bepaalt alleen welke kaart is verplaatst, waar die vandaan kwam en waar hij is beland. Elke library geeft u die vier feiten, en uw code maakt er een nieuw object van.
Schrijf die verplaatsfunctie als een pure helper en test hem zonder browser. dnd-kit levert er zelfs een mee, move uit @dnd-kit/helpers, die uw items en het drag-event aanneemt en de bijgewerkte kopie teruggeeft.
Waarom de native API lastiger is dan hij lijkt
De browser vuurt zeven events af (dragstart, drag, dragenter, dragleave, dragover, drop en dragend) en u moet dragover annuleren op elk geldig doel. Gegevens reizen als strings via event.dataTransfer, en u kunt ze alleen in de drop-handler lezen.
Er is geen pad voor het toetsenbord en geen ingebouwde manier om de andere kaarten geanimeerd opzij te laten schuiven. Dat is prima voor een bestand dat u op een uploadgebied neerzet, maar een sorteerbaar bord groeit al snel uit tot een kleine eigen library.
Sorteerbare lijst met dnd-kit
Installeer met npm install @dnd-kit/react. Elk item kent zijn eigen index; na een drop vertellen source.initialIndex en source.index waarheen het is verplaatst.
SortableList.jsx
Wijzigt de volgorde van een array met taaknamen. Eerst kopiëren en dan splice laat de oude state onaangeroerd.
Kanbanbord met dnd-kit
Voeg een group toe aan useSortable zodat kaarten tussen kolommen kunnen reizen. source.initialGroup en source.group zijn de oude en nieuwe kolomnamen.
KanbanBoard.jsx
Drie kolommen in één object. Verplaatsen binnen een kolom wijzigt de volgorde; verplaatsen naar een andere kolom haalt de kaart uit de ene array en voegt hem in de andere in.
Hetzelfde idee met native HTML drag-events
Geen pakket nodig. Let op de preventDefault in onDragOver: zonder die aanroep wordt de drop nooit uitgevoerd.
NativeColumns.jsx
Verplaatst een kaart naar het einde van de kolom waarop hij wordt neergezet. Voor het wijzigen van de volgorde binnen een kolom is extra indexlogica nodig.
Overzicht van HTML drag-events
De zeven drag-events en waar ze worden afgevuurd
Event
Afgevuurd op
Wanneer
Het gesleepte element
Het slepen begint; stel hier dataTransfer in
Het gesleepte element
Herhaaldelijk tijdens het slepen
Een mogelijk doel
Het gesleepte item komt erin
Een mogelijk doel
Herhaaldelijk zolang het erboven is; roep preventDefault aan om een drop toe te staan
Een mogelijk doel
Het gesleepte item verlaat het
Het doel
Het item wordt losgelaten op een geldig doel; lees hier dataTransfer
Het gesleepte element
Het slepen eindigt, neergezet of geannuleerd
Te doen
Bezig
Klaar
Logo
Prijstabel
Contactformulier
Herosectie
Domein
{card} verplaatst naar {column}, positie {n}
Probeer het: een werkend kanbanbord
Sleep kaarten tussen Te doen, Bezig en Klaar, of gebruik de verplaatsknoppen op elke kaart.