简介
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;