I'm currently trying to use a Drag & Drop Library called dnd-kit and its hook called useSortable.
So far I did achieved to make everything draggable the way I like, unfortunately somehow its not possible for me to update the state accordingly to the dragging.
Attached you can find also an example of my code.
I'm glad for every suggestion to solve my problem :)
import React, { useState } from "react";
import "./styles.css";
import { DndContext } from "@dnd-kit/core";
import { arrayMove, SortableContext, useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
function SortableItem({ item }) {
const { id, name } = item;
const {
attributes,
listeners,
setNodeRef,
transform,
transition
} = useSortable({ id: id });
const style = {
transform: CSS.Transform.toString(transform),
transition
};
return (
<li ref={setNodeRef} style={style} {...attributes} {...listeners} draggable>
Movement for {name}
</li>
);
}
export default function App() {
const [items, setItems] = useState([
{ id: 1, name: "Items One" },
{ id: 2, name: "Item 2" },
{ id: 3, name: "Items 3" }
]);
const handleDragEnd = (event) => {
console.log(event);
const { active, over } = event;
if (active.id !== over.id) {
setItems((items) => {
console.log(items);
const oldIndex = items.indexOf(active.id);
const newIndex = items.indexOf(over.id);
const newItemsArray = arrayMove(items, oldIndex, newIndex);
return newItemsArray;
});
}
};
console.log(items);
return (
<div className="App">
<h1>Sorting Example</h1>
<DndContext onDragEnd={handleDragEnd}>
<SortableContext items={items}>
{items.map((item) => (
<SortableItem key={item.id} item={item} />
))}
</SortableContext>
</DndContext>
</div>
);
}
You're main issue is in these lines:
Since you're using an array of objects and not just an array, you'll need to find the index through
find
as well and not justindexOf
to get its index. Like so:If you're using typescript, any linting can complain that
oldItem
ornewItem
can beundefined
andindexOf
doesn't acceptundefined
s, so you can just use!
to force it because you know that the item will exist (usually), e.g.:const oldIndex = items.indexOf(oldItem!);
Update: or even better/cleaner using
findIndex
as suggested by @Ashiq Dey: