React Dnd 基本拖放功能实现及 API 整理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Dnd 基本拖放功能实现及 API 整理相关的知识,希望对你有一定的参考价值。

参考技术A 一个容器,在这个容器中的元素可以进行拖放的操作。

一个 hook 函数,可以让一个 DOM 元素实现拖拽效果。

一个 hook 函数,可以让一个 DOM 元素能够放置拖拽元素。

简单梳理下所有的 API

这个 hook 函数返回一个数组。
index 0 一个对象,它是从配置中的 collect 函数来定义的。
index 1 一个连接器函数,用在 React 的 ref 属性。连接了能够拖拽的元素。
index 2 一个连接器函数,用在 React 的 ref 属性。连接了会被拖拽的元素。
PS; 1 和 2 可以用来实现拖拽元素 A 中的元素 B,元素 A 跟着移动。

下面是 Hook 函数中的配置对象元素:

个人感觉 item 和 collect 最常用,begin 函数和 end 函数也比较常用。梳理下来还是挺简单的。

这个 hook 函数返回一个数组:

index 0 collect 函数返回的对象,如果没有对象可以返回空。
index 1 一个连接器函数,用在 React 的 ref 属性。连接了能够放置的元素。

下面是配置对象元素:

这是一个 React 容器组件,在这个容器组件中的元素才可以实现拖放。

它一共三个 props:

暂时就这么多,简单写了个 demo,然后了解了一下用到的 API。其实仔细了解之下还是蛮简单的。还有 useDragLayer 和 DragPreviewImage 两个 API 没用到,但应该都不难。
明天我试着写个更加复杂的例子分享出来。

使用 react-dnd 和 useDrag 和 useDrop 进行测试

【中文标题】使用 react-dnd 和 useDrag 和 useDrop 进行测试【英文标题】:Tests using react-dnd with useDrag and useDrop 【发布时间】:2020-01-19 12:30:21 【问题描述】:

有没有人能够使用带有 useDrag 和 useDrop 钩子的功能组件测试来自 https://github.com/react-dnd/react-dnd 的拖放功能?

根据在此处找到的示例http://react-dnd.github.io/react-dnd/docs/testing,它们要么使用 DragSource 或 DropTarget HOC 装饰原始组件。 例如:

// ...

export interface BoxProps 
    name: string

    // Collected Props
    isDragging: boolean
    connectDragSource: ConnectDragSource

const Box: React.FC<BoxProps> = ( name, isDragging, connectDragSource ) => 
    const opacity = isDragging ? 0.4 : 1
    return (
        <div ref=connectDragSource style= ...style, opacity >
            name
        </div>
    )


export default DragSource(
    ItemTypes.BOX,
    
        beginDrag: (props: BoxProps) => ( name: props.name ),
        endDrag(props: BoxProps, monitor: DragSourceMonitor) 
            const item = monitor.getItem()
            const dropResult = monitor.getDropResult()

            if (dropResult) 
                alert(`You dropped $item.name into $dropResult.name!`)
            
        ,
    ,
    (connect: DragSourceConnector, monitor: DragSourceMonitor) => (
        connectDragSource: connect.dragSource(),
        isDragging: monitor.isDragging(),
    ),
)(Box)

示例取自https://github.com/react-dnd/react-dnd/blob/master/packages/documentation/examples-decorators/src/01-dustbin/single-target/Box.tsx

我找不到任何使用他们的钩子进行测试的例子。他们确实有使用装饰器和挂钩的代码示例 (https://github.com/react-dnd/react-dnd/tree/master/packages/documentation),但也有仅使用装饰器的测试示例。

【问题讨论】:

你找到解决办法了吗,我正在尝试用这种方式解决排序 并非如此。他们承认他们的 API 需要解决这个问题:github.com/react-dnd/react-dnd/issues/1540 【参考方案1】:

我从 github 票上复制了这个并为我工作:

const dragAndDrop = (src: Element, dst: Element) => 
  fireEvent.dragStart(src);
  fireEvent.dragEnter(dst);
  fireEvent.drop(dst);
  fireEvent.dragLeave(dst);
  fireEvent.dragEnd(src);
 ;
const allSections = rendered.getAllByRole('dropzone');

const marketSection = allSections[0];
const marketExpandedSection = allSections[1];

const basisIdDrag = within(marketSection).getByRole('draggable');

act(() => 
  dragAndDrop(basisIdDrag, marketExpandedSection);
);

【讨论】:

以上是关于React Dnd 基本拖放功能实现及 API 整理的主要内容,如果未能解决你的问题,请参考以下文章

使用 react-beautiful-dnd 嵌套拖放

如何在 react-dnd-treeview 库上使用 Selenium 测试拖放

使用 ReactJs 和 react-dnd 拖放可排序列表的问题

react-dnd 中的动画

使用 react-dnd 和 useDrag 和 useDrop 进行测试

react-dnd 使用