React Dnd-Kit 入门
在本文中,我们将使用其中一个拖放库进行反应。很少有像react-dnd、dnd-kit和react-beautiful-dnd这样的反应好的拖放库。
我们今天将研究 dnd-kit 使用这个库的原因是它支持很多用例、钩子的可用性、轻量级等。
首先,让我们使用 create-react-app 创建一个反应应用程序并使用它安装必要的库
npx create-react-app react-dndkit-eg
npm install --save @dnd-kit/core @dnd-kit/sortable
@dntkit/core 和 @dndkit/sortable 这两个库是我们支持基本拖放功能所需要的,库还提供对其他库(如@dnd-kit/utilities、@dnd-kit/modifiers、@dnd-kit/accessibility)的各种其他功能的支持,可以阅读有关每个库的更多详细信息在他们的网站上。
首先,我们将创建一个组件,该组件将包装我们的可拖动/可排序组件,简单来说,dnd 的整个想法就是拥有一个容器,您的项目可以在其中拖入或移动,因此有关该组件的代码看起来会有点像这样sortable-component-complete-code
...
# e.g code snippet
export function SortableItem(props) {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
} = useSortable({id: props.id});
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
if(props.handle) {
return (<div ref={setNodeRef} style={style} {...attributes} className={'pos-relative'}>
{
props.handle ?
<span className='dragHandleClass' {...listeners}>
# some svg/img/htmlelement
</span>
: null
}
{props.children}
</div>)
}
return (
<div ref={setNodeRef} style={style} {...attributes} {...listeners} className={'pos-relative'}>
{props.children}
</div>
);
}
...
进入全屏模式 退出全屏模式
上面的代码是对需要拖拽/排序的组件的封装,后面会讲到handle prop,将idprop传递给useSortable hook,这样每个item都可以被唯一标识。
现在让我们创建一个组件,该组件将包含多个可以排序或拖动的项目,以创建一个我们需要 DndContext 和 SortableContext 的容器,以便可以移动/排序网格和行元素。
DndContext 需要一些道具,其中一些是传感器,collisionDetection 等,这些还包括像 handleDragStart 和 handleDragEnd 这样的函数,这些是可以在整个拖放交互之前和之后使用的函数。
Similarly SortableContext takes few props , here we will have to pass items which should be an array on uniqueIds & this should be same as that we have passed to sortableItem above.
上下文的代码应该类似于这个sortable-context-complete-code
...
# e.g sortable context/container
<DndContext
id={'grid-dnd-basic'}
onDragEnd={handleDragEnd}
sensors={sensors}
collisionDetection={closestCenter}
>
<SortableContext
id={'grid-sort-contextbasic'}
items={items.map((i) => i?.id)}
>
{items.map(value => {
return (
<SortableItem handle={true} key={value?.id} id={value?.id} >
# sortableItem Content
</SortableItem>
)
})}
</SortableContext>
</DndContext>
...
进入全屏模式 退出全屏模式
至此,我们完成了有关拖放的组件设置,现在我们必须将处理程序添加到诸如 handleDragStart/handleDragEnd 之类的函数中,这些代码与 dnd-kit 文档提供的代码几乎相似,唯一的变化是 items 属性传递给处理函数
function handleDragEnd(event) {
const {active, over} = event;
if (active.id !== over.id) {
setItems((items) => {
const oldIndex = (items.map(i => i.id)).indexOf(active.id);
const newIndex = (items.map(i => i.id)).indexOf(over.id);
return arrayMove(items, oldIndex, newIndex);
});
}
}
进入全屏模式 退出全屏模式
在上面的代码中,您可以看到我们使用 map 函数仅传递 indexOf 函数的 id,因为所有内容都映射到传递给可排序项目和可排序上下文的唯一 Id。
所以我们几乎已经准备好使用 dndContext 和 sortableContext 进行排序的 dnd-kit 实现了。
Now lets visit the handle prop that we have used earlier in our sortableItem, so we can see useSortable provides a listeners now if we want to drag the item using some handler and not the actual item then we can use handle prop to apply listener to the drag-handler directly, in this way we will be able to drag via some handler and not he actual item
# e.g handle implementation
...
if(props.handle) {
return (<div ref={setNodeRef} style={style} {...attributes} className={'pos-relative'}>
{
props.handle ?
<span className='dragHandleClass' {...listeners}>
# svg/image/html-element
</span>
: null
}
{props.children}
</div>)
}
...
进入全屏模式 退出全屏模式
现在让我们来谈谈整个传感器例如,我们将在文档中使用与此类似的基本传感器实现
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
进入全屏模式 退出全屏模式
现在这些使用传感器将第二个参数作为对象,该对象也具有属性activationConstraint,现在这可以用于仅在一些像素移动代码后激活传感器。
const sensors = useSensors(
useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
进入全屏模式 退出全屏模式
The scenarios where this can be used is when you have an click listener to you sortableItem & you don't use drag-handle, so that we can uniquely identify click & drag events, without this constraint event click will be treated as drag events & our drag-handler functions like onDragEnd & onDragStart will be triggered.
本文主要涵盖与dndContext和sortable预设相关的主题,更多关于相同的内容可以在 dnd-kit 网站上阅读。
与文章相关的代码存在于GithubLink&gh-pages
更多推荐

所有评论(0)