如何实现 react-dnd useDragLayer?
Posted
技术标签:
【中文标题】如何实现 react-dnd useDragLayer?【英文标题】:How to implement react-dnd useDragLayer? 【发布时间】:2021-11-25 03:08:49 【问题描述】:我有一个组件当前使用useDrag 挂钩连接到 react-dnd。它运行良好,除了预览。正如许多在线线程所建议的那样,我想实现 useDragLayer 来查看它是否有助于解决我的预览问题。
这是我当前的(简化的)useDrag 实现:
const [ isDragging , connectDragSource, connectPreview] = useDrag(
item,
collect: monitor => (
isDragging: monitor.getItem()?.index === item.index,
)
)
return (
<Wrapper ref=connectPreview isDragging=isDragging>
<DragHandle ref=connectDragSource />
</Wrapper>
)
如何在这种情况下使用useDragLayer
,以有助于我的预览?文档示例对我来说毫无意义...
如何使用useDragLayer
api 连接我渲染的组件? useDragLayer
不返回拖动源和预览连接器函数(就像 useDrag
在返回数组的索引 1 和 2 上所做的那样),并且它的 collect 函数也不提供 DragSourceConnector 实例。那么调用后的钩子/返回值该怎么办呢?
【问题讨论】:
【参考方案1】:我刚刚解决了这个问题并想分享它以帮助其他人:)
您需要做几件事才能使其充分发挥作用。
-
通过添加以下 useEffect 禁用默认预览行为
import getEmptyImage from "react-dnd-html5-backend";
const [ isDragging , drag, dragPreview] = useDrag(() => (
type: "BOX",
collect: (monitor) => (
isDragging: monitor.isDragging(),
),
));
useEffect(() =>
dragPreview(getEmptyImage(), captureDraggingState: true );
, []);
-
创建自定义默认图层
export const CustomDragLayer = (props: ) =>
const
itemType,
isDragging,
initialCursorOffset,
initialFileOffset,
currentFileOffset,
= useDragLayer((monitor) => (
item: monitor.getItem(),
itemType: monitor.getItemType(),
initialCursorOffset: monitor.getInitialClientOffset(),
initialFileOffset: monitor.getInitialSourceClientOffset(),
currentFileOffset: monitor.getSourceClientOffset(),
isDragging: monitor.isDragging(),
));
if (!isDragging)
return null;
return (
<div style=layerStyles>
<div
style=getItemStyles(
initialCursorOffset,
initialFileOffset,
currentFileOffset
)
>
<div>Your custom drag preview component logic here</div>
</div>
</div>
);
;
const layerStyles: CSSProperties =
position: "fixed",
pointerEvents: "none",
zIndex: 100,
left: 0,
top: 0,
width: "100%",
height: "100%",
border: "10px solid red",
;
function getItemStyles(
initialCursorOffset: XYCoord | null,
initialOffset: XYCoord | null,
currentOffset: XYCoord | null
)
if (!initialOffset || !currentOffset || !initialCursorOffset)
return
display: "none",
;
const x = initialCursorOffset?.x + (currentOffset.x - initialOffset.x);
const y = initialCursorOffset?.y + (currentOffset.y - initialOffset.y);
const transform = `translate($xpx, $ypx)`;
return
transform,
WebkitTransform: transform,
background: "red",
width: "200px",
;
-
将
<CustomDragLayer />
添加到***组件
您需要将ref=drag
包含到要拖动的组件中,并完全删除connectPreview
引用。
希望对您有所帮助。
【讨论】:
以上是关于如何实现 react-dnd useDragLayer?的主要内容,如果未能解决你的问题,请参考以下文章
react-dnd 的 connectDragPreview() 是如何工作的?
react-dnd 简单的可排序示例 ES6 而不是 ES7