React-Beautiful-DnD是一個很有人氣的 DnD 套件,除了基本的 Drag & Drop 功能之外,還有優雅的拖曳動畫、鍵盤拖曳支援等,使用起來也很容易入手。
基本要素
React-Beautiful-DnD由三種要素組成,分別為:<DragDropContext />、<Draggable />、<Droppable />
下圖為官方的示意圖:

DragDropContext
開發 React 的人對於<DragDropContext />應該不難理解,
看到context這個關鍵字就能領略箇中含義,
<DragDropContext />所定義的是要實作拖拉功能的範圍
Draggable
定義拖曳元件,將所要拖曳的元件包在<Draggable />裡面,結構如下:
import { Draggable } from "react-beautiful-dnd";
<Draggable draggableId={taskId} index={taskIndex}>
{(provided, snapshot) => {
const { draggableProps, dragHandleProps, innerRef } = provided;
const { isDragging } = snapshot;
return (
<div ref={innerRef} {...draggableProps} {...dragHandleProps} data-is-dragging={isDragging}>
<h4>I can DRAG! ✋</h4>
</div>
);
}}
</Draggable>;
要拖曳的元件不能直接作為children直接包在<Draggable />中間,
必須是一個函式(官方的教學影片說裡面是放一個renderProps),並在return的時候返回我們要拖拉的元件,
而函式的參數中,有<Draggable />的兩個物件:provided及snapshot
provided
provided物件中包含draggableProps、dragHandleProps及innerRef
innerRef:用來綁定拖曳的 DOM 元素draggableProps:提供拖曳元件的propsdragHandleProps:則可另外定義拖拉的範圍,像是綁定一個 Icon 做這個拖曳元件的拖拉
snapshot
snapshot物件中,我目前使用到的只有isDragging,在拖曳的狀態下,可以用來做樣式上的變換
Droppable
定義放置的元件,如同<Draggable />一樣的結構,只是是加上放置的屬性,結構如下:
import { Droppable } from "react-beautiful-dnd";
<Droppable droppableId={columnId} type="task">
{(provided, snapshot) => {
const { droppableProps, innerRef, placeholder } = provided;
const { isDraggingOver } = snapshot;
return (
<div ref={innerRef} {...droppableProps} data-is-over={isDraggingOver}>
<h2>Drop on ME!! 🙌</h2>
{placeholder}
</div>
);
}}
</Droppable>;
provided
provided物件中包含droppableProps、placeholder及innerRef
innerRef:用來綁定可放置的 DOM 元素droppableProps提供放置元件的propsplaceholder就如其名,是一個佔位元素,在拖曳(但尚未 drop)的時候,提供一個放置的空間
snapshot
snapshot物件中,我目前使用到的只有isDraggingOver,在被拖曳元件 hover 的狀態下,用來做樣式上的變換
最後附上範例連結