22日目を担当します、@Ayako_0224と申します。
よければ去年の記事もご覧ください。
概要
本記事ではReactのドラッグ&ドロップソートライブラリのdnd-kitを紹介させていただきます。
他にも類似のライブラリはいくつかありますが選定基準はこちらを参考にさせていただきました。
完成系
実際に作ったものはこちらです。
codesandboxでサンプルコードを公開しています。
インストール手順
npmでインストールするだけです。
今回の例では基本のcoreと動きをなめらかにするためのutilitiesとソートする機能が備わっているsortableをインストールしています。
npm install @dnd-kit/core @dnd-kit/utilities @dnd-kit/sortable
sensor、contextの設定
スマホなどのタッチデバイスやマウス、キーボードのドラッグを検知するためにsensorsを記述します。
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
sensorのライフサイクルには以下の6つがあります。
- アクティベーターイベントの検出
- センサーの初期化
- ドラッグ開始イベントのディスパッチ
- ドラッグ移動イベントのディスパッチ
- ドラッグ終了またはドラッグキャンセルイベントのディスパッチ
- センサーのクリーンアップ
これをDndContextプロバイダーにセットしSortableContextプロバイダーに並び替え対象のitemsをおくことで子要素がドラッグ&ドロップできるようになります。
<DndContext sensors={sensors} onDragEnd={onDragEnd}>
<SortableContext items={items}>
{...子要素}
</SortableContext>
</DndContext>
並び替えの実装
動かせるようになれば後はその並びを保持するだけです。
onDragEndプロパティに以下の関数を設定しましょう。
const onDragEnd = ({ active, over }: DragEndEvent) => {
if (over && active.id !== over?.id) {
const activeIndex = items.findIndex(({ id }) => id === active.id);
const overIndex = items.findIndex(({ id }) => id === over.id);
onChange(arrayMove(items, activeIndex, overIndex));
}
};
DragEndEventは以下の2つのプロパティを持っています。
- active: 現在ドラッグされているアイテムでidなどの情報を含む
- over: ドラッグ中にアイテムが重なっているターゲットエリアでこちらもidを持つ
ドラッグ中のアイテムがどこからどこに移動しようとしているのかを見て並び替えをしています。
最後に
簡単にドラッグ&ドロップが実装できることをお伝えしたつもりですがいかがでしたでしょうか?
ライブラリが豊富なことがReactの魅力の1つでもあると思います。
皆さんもぜひdnd-kitライフを楽しんでみてください!