Build React Drag N Drop With Dnd Kit
In this post you will learn how to implement drag and drop inside React.
The main problem with drag n drop is that it takes quite a lot of effort to implement it without library. This is why I highly recommend you to pick good library for this.
What library to pick?
But here is the problem. If you google "react drag n drop" the top result are libraries which are either abandoned or the API for them is really strange or not comfortable. For example react-beautiful-dnd
is not maintained and react-dnd
which works is not that comfortable to use.
This is why what I recommend you is dnd-kit
. It is a good modern library with comfortable API.
Here we have lots of stuff like Droppable
, Draggable
, different sensors (also for touch devices) and also Sortable
.
The whole library is built with hooks, this is exactly what we want.
Adding Dnd Kit
The goal of this video to implement this is with sorting based on the drag n drop.
Here we have a list of users and a possibility to add new user to the list. We just need to attach drag and drop to sort this list.
Let's install all needed dependencies.
npm i@dnd-kit/core @dnd-kit/utilities @dnd-kit/sortable
This is what we need to implement sort. If you just need drag and drop you don't need sortable
.
<DndContext collisionDetection={closestCenter} onDragEnd={onDragEnd}>
{users.map((user) => (
<div key={user.id} className="user">{user.name}</div>
))}
</DndContext>
Here we wrapped our list of users with DndContext
. It's a container where we can drag and drop. Inside we provide collisionDetection
which defines how element will react and onDragEnd
callback which we need to implement.
<DndContext collisionDetection={closestCenter} onDragEnd={onDragEnd}>
<SortableContext items={users} strategy={verticalListSortingStrategy}>
{users.map((user) => (
<div key={user.id} className="user">{user.name}</div>
))}
</SortableContext>
</DndContext>
Now we added SortableContext
which is used for sorting the list. We set verticalListSortingStrategy
inside as our list goes in vertical direction.
Adding useSortable
We also need to move every single element in additional component because for each element we must call a hook inside.
const SortableUser = ({ user }) => {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
} = useSortable({ id: user.id });
const style = {
transition,
transform: CSS.Transform.toString(transform),
};
return (
<div
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
className="user"
>
{user.name}
</div>
);
};
Here is our additional component. We used useSortable
where we provided unique ID. We also attached lots of styles, attributes and listeners from this library to every element.
<DndContext collisionDetection={closestCenter} onDragEnd={onDragEnd}>
<SortableContext items={users} strategy={verticalListSortingStrategy}>
{users.map((user) => (
<SortableUser key={user.id} user={user} />
))}
</SortableContext>
</DndContext>
This is how our markup look now.
Sorting an array
Our last step is to implement onDragEnd
callback and resort the list based on dragged element.
const onDragEnd = (event) => {
const { active, over } = event;
if (active.id === over.id) {
return;
}
setUsers((users) => {
const oldIndex = users.findIndex((user) => user.id === active.id);
const newIndex = users.findIndex((user) => user.id === over.id);
return arrayMove(users, oldIndex, newIndex);
});
};
Here we get an event from dnd kit with all information about what we dragged and at what position. To sort our array and switch positions we use a helper from this library which is called arrayMove
. It returns a new array with switched position.
As you can see in browser our drag n drop is fully working.
Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!
📚 Source code of what we've done