作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在尝试使用名为 dnd-kit 的拖放库 及其名为 useSortable 的钩子(Hook)。
到目前为止,我确实做到了让一切都可以按照我喜欢的方式拖动,不幸的是,不知何故我无法根据拖动更新状态。
附件中还有我的代码示例。
我很高兴每一个解决我问题的建议:)
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>
);
}
最佳答案
您的主要问题在于以下几行:
const oldIndex = items.indexOf(active.id);
const newIndex = items.indexOf(over.id);
由于您使用的是对象数组而不仅仅是数组,因此您还需要通过 find
而不仅仅是 indexOf
来找到索引它的指数。像这样:
const oldItem = items.find({ id }) => id === active.id)
const newItem = items.find({ id }) => id === over.id)
const oldIndex = items.indexOf(oldItem);
const newIndex = items.indexOf(newItem);
const newItemsArray = arrayMove(items, oldIndex, newIndex);
如果您使用的是 typescript,任何 linting 都会提示 oldItem
或 newItem
可以是 undefined
和 indexOf
不接受 undefined
,所以你可以使用 !
来强制它,因为你知道该项目将存在(通常),例如:const oldIndex = items.indexOf(oldItem!);
更新:或者根据 @Ashiq Dey 的建议使用 findIndex
甚至更好/更干净:
const oldIndex = items.findIndex({ id }) => id === active.id)
const newIndex = items.findIndex({ id }) => id === over.id)
const newItemsArray = arrayMove(items, oldIndex, newIndex);
关于javascript - 如何更新 DnD 组件的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67738882/
我是一名优秀的程序员,十分优秀!