关于 dnd-kit-implementation
dnd-kit-implementation 是使用 dnd-kit 实现拖放交互的开发技能,面向构建可排序容器和可放置目标的开发者。它通过拖动上下文切换容器行为,并给出状态更新模式。
主要功能
- 01组合可排序与可放置行为
- 02根据拖动上下文切换逻辑
- 03通过 ID 前缀区分容器与项目
- 04使用不可变状态更新
适用场景
- 01重排看板列并移动卡片
- 02整理文件夹并移动文件
- 03调整播放列表及歌曲顺序
- 04重排任务列表并移动任务
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ atman-33/ skills --skill dnd-kit-implementation安装后在 Claude Code 中输入/dnd-kit-implementation确认已加载。
附带文件references/implementation-patterns.mdreferences/state-management.md
详细介绍
dnd-kit 实现指南
概述
此技能提供了使用 dnd-kit 库实现拖放功能的模式,可同时支持可排序容器和可放置目标。
核心概念
组合使用 useSortable 和 useDroppable 的关键在于基于拖动上下文的条件逻辑:
- 拖动项目时 → 容器仅作为放置目标
- 拖动容器时 → 容器作为可排序元素
实现方式是检测当前正在拖动的对象,并仅启用相应的功能。
实现模式
容器组件结构
const SortableDroppableContainer = ({ container }) => {
// useSortable for container reordering
const {
attributes,
listeners,
setNodeRef: setSortableRef,
transform,
transition,
isDragging,
} = useSortable({ id: container.id });
// useDroppable for receiving items
const { setNodeRef: setDroppableRef, isOver } = useDroppable({
id: container.id,
});
// Active element from context
const { active } = useDndContext();
// Determine behavior based on what's being dragged
const isItem = active?.id?.toString().startsWith('item-');
const isContainer = active?.id?.toString().startsWith('container-');
// Apply conditional refs
const setNodeRef = isItem ? setDroppableRef : setSortableRef;
return (
<div ref={setNodeRef} {...(isContainer ? attributes : {})} style={style}>
<div {...(isContainer ? listeners : {})}>{/* Drag handle */}</div>
{/* Container content */}
</div>
);
};
关键实现要点
- 双钩子用法:在同一组件中同时使用
useSortable和useDroppable - 上下文检测:使用
useDndContext()检查当前正在拖动的对象 - 条件引用:根据拖动状态应用相应的 ref
- ID 命名约定:使用
container-*和item-*等前缀区分类型
ID 命名约定
// Containers
const containerId = `container-${id}`;
// Items
const itemId = `item-${id}`;
这一约定使条件逻辑清晰且易于维护。
状态管理关键点
更新容器项目时,始终创建新对象:
// ❌ Won't trigger re-render
containers.items.push(newItem);
// ✅ Correct - creates new reference
setContainers(prev => prev.map(c =>
c.id === targetId
? { ...c, items: [...c.items, newItem] }
: c
));
常见用例
- 看板:重新排列列,并在列之间移动卡片
- 文件管理:重新整理文件夹,并将文件移入文件夹
- 播放列表编辑器:重新排列播放列表,并向播放列表添加歌曲
- 任务管理器:重新排列任务列表,并在列表之间移动任务
参考资料
如需详细的实现示例和代码模式,请参阅:
- implementation-patterns.md - 包含 TypeScript 的完整组件示例
- state-management.md - 状态更新模式和常见陷阱
评论
支持 Markdown