react dnd学习文档

692 阅读1分钟

简介

React DnD 是一组 React 高阶组件,使用的时候只需要使用对应的 API 将目标组件进行包裹,即可实现拖动或接受拖动元素的功能。

核心api

DndProvider

如果想要使用 React DnD,首先需要在外层元素上加一个 DndProvider。

import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

<DndProvider backend={HTML5Backend}>
    <App />
</DndProvider>

backend

React DnD 将 DOM 事件相关的代码独立出来,将拖拽事件转换为 React DnD 内部的 redux action。由于拖拽发生在 H5 的时候是 ondrag,发生在移动设备的时候是由 touch 模拟,React DnD 将这部分单独抽出来,方便后续的扩展,这部分就叫做 Backend。它是 DnD 在 Dom 层的实现。

  • react-dnd-html5-backend : 用于控制html5事件的backend
  • react-dnd-touch-backend : 用于控制移动端touch事件的backend
  • react-dnd-test-backend : 用户可以参考自定义backend

useDrag

让DOM实现拖拽能力的构子

import { useDrag } from 'react-dnd';
import styles from './index.less';

function Box() {
    const [{ isDragging }, drag, dragPreview] = useDrag({
        type: 'BOX',
        // 数据
        item: {
            type: '111',
            index: 1
        },
        collect: (monitor) => ({
            isDragging: monitor.isDragging()
        })
    })

    return (
        <div ref={dragPreview} className={styles.box} style={{
            background: 'green',
            opacity: isDragging ? 0.5 : 1
        }}>
            <div role="Handle" ref={drag} className={styles.box}>可拖拽组件BOX</div>
        </div>
    )
}

export default Box;

useDrop

实现拖拽物放置的钩子

import { useDrop } from 'react-dnd';
import styles from './index.less';

function Bucket() {
    const [{ canDrop, isOver }, drop] = useDrop(() => ({
        accept: 'BOX',
        drop(item, monitor) {
            console.log("🚀 ~ file: Bucket.tsx:8 ~ drop ~ item:", item)
        },
        collect: (monitor) => ({
            isOver: monitor.isOver(),
            canDrop: monitor.canDrop()
        })
    }))

    return (
        <div ref={drop} className={styles.bucket} style={{ backgroundColor: isOver ? 'red' : 'white' }}>
            {canDrop ? 'Release to drop' : 'Drag a box here'}
        </div>
    )
}

export default Bucket;