React Beautiful Dnd 快速使用筆記

react-beautiful-dnd 有 3 個主要元件:

  • DragDropContext - 建立一個可 DnD 的範圍。
    • onDragStart
    • onDragUpdate
    • onDragEnd
  • Droppable - 建立可以被拖曳放入的區塊。
  • Draggalbe - 可被拖拉元件
  1. 安裝
1
$ npm i react-beautiful-dnd
  1. 於希望 DnD 的位置使用 DragDropContext 包起來,且 onDragEnd 必須設定:
1
2
3
4
5
6
7
import { DragDropContext } from 'react-beautiful-dnd';

<DragDropContext
onDragEnd={() => {}}
>
{/* Your target */}
</DragDropContext>
  1. 使用 Droppable 配置可被拖入的區塊
    • Droppable 必須設定 droppableId
    • Droppable 使用 render props pattern 意味著內部須使用一個 function。這個 function 使用 provided 將所需的參數代置 DOM
    • provided 是一個物件
      • provided.droppableProps,該參數須套用至欲被拖放的 DOM 上
      • ref 參數須設定
      • provided.placeholder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
impoort { Droppable } from 'react-beautiful-dnd';

<Droppable droppableId="id">
{
provided => (
<List
ref={provided.innerRef}
{...provided.droppableProps}
>
{provided.placeholder}
</List>
)
}
</Droppable>
  1. 將可被拖移的元件使用 Draggable 包起來:
    • draggableIdindex 必須。
    • Droppable 一樣,children 為 render props pattern
    • 內部項目 ref 須設定,provided.draggablePropsprovided.dragHandleProps 須套用至元件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Draggable
draggableId={t.id}
index={i}
>
{p => (
<Item
ref={p.innerRef}
{...p.draggableProps}
{...p.dragHandleProps}
key={t.id}
>
{t.text}
</Item>
)}
</Draggable>
  1. onDragEnd 變更排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// onDragEnd(result) result 資訊

const result = {
draggableId: 1,
type: 'TYPE',
reson: 'DROP',
source: {
droppableId: 1,
index: 0,
},
destination: {
droppableId: 1,
index: 1,
}
}

Reorder:

1
2
3
4
5
6
7
8
9
10
11
12
13
onDragEnd={result => {
const { source, destination, draggableId } = result;
if (!destination) {
return;
}

let arr = Array.from(this.state.todos);
const [remove] = arr.splice(source.index, 1);
arr.splice(destination.index, 0, remove);
this.setState({
todos: arr,
});
}}

在拖拉的時候,Droppable, Draggable 元件除了 provided 之外還提供了 snapshot

下面是 snapshot 提供的資訊:

1
2
3
4
5
6
7
8
9
const draggableSnapshot = {
isDragging: true,
draggingOver: 'droppable-id'
}

const droppableSnapshot = {
isDraggingOver: true,
draggingOverWith: 'draggable-id'
}

回到 DragDropContext 除了 onDragEnd 之外還有 onDragStartonDragUpdate 兩個 events
這兩個事件可以協助我們加入一些樣式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// onDragStart
const start = {
draggableId: 'draggalbe-id',
type: 'TYPE',
source: {
droppableId: 'droppable-id',
index: 0,
}
}

// onDragUpdate
const update = {
...start,
destination: {
droppableId: 'droppable-id',
index: 1,
}
}
  • drag handle 是 Draggable 的一部分用來處理可拖拉的部分(可拖拉整個元件或局部)。
  • 要停止拖拉可以設定 isDragDisabled
  • Droppable 可以限制可被拖入的元件:
    • type 同樣 type 的 Droppable 可以互相拖移
    • isDropDisabled 控制可否被拖入
作者

andyyou(YOU,ZONGYAN)

發表於

2019-06-04

更新於

2023-12-05

許可協議