Multiple sortable lists
Learn how to reorder sortable elements across multiple lists.
Overview
In this guide, you’ll learn how to reorder sortable elements across multiple lists. This is useful when you have multiple lists and you want to move elements between them.
Before getting started, make sure you familiarize yourself with the useSortable hook.
We’ll be setting up three columns, and each column will have its own list of items. You’ll be able to drag and drop items between the columns.
Setup
First, let’s set up the initial setup for the columns and items. We’ll be creating three files, App.js
, Column.js
, and Item.js
, and applying some basic styles in the Styles.css
file.
Adding drag and drop functionality
Now, let’s add drag and drop functionality to the items. We’ll be using the useSortable hook to make the items sortable. Let’s modify the Item
component to make it sortable:
As you can see, we’ve added the useSortable
hook to the Item
component. We’ve also passed the id
, index
, type
, accept
, and group
props to the hook.
This creates an uncontrolled list of sortable items that can be sorted within each column, and across columns thanks to the group
property. However, in order to be able to move items to an empty column, we need to add some additional logic.
Moving items between columns
To move items to empty columns, we need to add make each column droppable.
We’ll be using the useDroppable hook to create a drop target for each column. Let’s modify the Column
component to make it droppable:
collisionPriority
to CollisionPriority.Low
to prioritize collisions of items over collisions of columns. Learn more about detecting collisions.This will allow us to drop items into each column. However, we still need to handle the logic for moving items between columns.
We’ll be using the DragDropProvider component to listen and respond to the drag and drop events. Let’s modify the App
component to add the DragDropProvider
. We’ll be using the move
helper function from @dnd-kit/helpers
to help us mutate the array of items between columns:
As you can see, we’ve added the DragDropProvider
component to the App
component. We’ve also added an onDragOver
event handler to listen for drag and drop events.
When an item is dragged over a column, the onDragOver
event handler will be called. We’ll use the move
helper function to move the item between columns.
The result is a sortable list of items that can be moved between columns.
Making the columns sortable
If you want to make the columns themselves sortable, you can use the useSortable
hook in the Column
component.
Here’s how you can modify the Column
component to make it sortable:
index
prop to the Column
component in the App
component.If we want to control the state of the columns in React, we can update the App
component to handle the column order in the onDragEnd
callback:
We’re using the onDragEnd
event handler instead of the onDragOver
event handler to handle the column order. This allows us to only update the order of the columns in React when the drag operation is completed, while letting @dnd-kit
optimistically update the order of the columns during the drag operation, without causing unnecessary re-renders.
If we wanted more control over the drag and drop operation, we could also handle the event in the onDragOver
callback.
Handling canceled drag operations
It’s possible for a drag operation to be canceled. For example, users can cancel a drag operation initiated by the Pointer sensor by pressing the Escape
key.
When you update the order of items in the onDragOver
callback, you should make sure to check if the user decided to abort the drag operation in the onDragEnd
callback. If the drag operation was canceled, you should revert the order of items to the state before the drag operation started.
For example, here is how we would update our app to handle this case for the order of items:
@dnd-kit
are automatically reverted when a drag operation is canceled.