UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【dnd-kit】 useSortable と useDroppable の違い

以前、dnd-kit というライブラリを調べたことがあった

uga-box.hatenablog.com

今回は実際に使ってみて useSortable と useDroppable についてわかったことをまとめる

useDroppable の概要

useDroppable は、ドラッグ対象を受け入れる領域(ドロップゾーン)を定義するフック

Droppable | @dnd-kit – Documentation

このフックを使用することで、特定のエリアに対して「ここにドロップ可能」という判定が機能する

主な用途

  • ゴミ箱エリアへのドロップ
  • リストやコンテナへの追加処理
  • 特定ゾーンでのドラッグアクション受け入れ

使用例

const { setNodeRef, isOver } = useDroppable({ id: 'drop-zone' });

return (
  <div ref={setNodeRef} style={{ backgroundColor: isOver ? '#e0e0e0' : '#ffffff' }}>
    ドロップエリア
  </div>
);

setNodeRef を対象のDOM要素に指定することで、そのエリアが有効なドロップ先として認識される

isOver を利用すれば、ドラッグ中にその領域にカーソルが重なっているかどうかを判定できる

useSortable の概要

useSortable は、要素を並び替え可能にするフック

Sortable | @dnd-kit – Documentation

内部的には useDraggable と useDroppable を組み合わせた構造になっており、リストやボード内で要素の順序を変更する用途で使用する

主な用途

-リスト内でのアイテム並び替え - 複数リスト間での要素移動 - ドラッグ&ドロップによる順序変更の実装

使用例

const { setNodeRef, attributes, listeners, transform, transition } = useSortable({ id: 'item-1' });

return (
  <div
    ref={setNodeRef}
    {...attributes}
    {...listeners}
    style={{
      transform: CSS.Transform.toString(transform),
      transition,
    }}
  >
    並び替え可能なアイテム
  </div>
);

listeners を適用することでドラッグ操作が有効になる

transform と transition により、ドラッグ中のアニメーションも制御される

両者の違いと使い分け

項目 useDroppable useSortable
目的 ドロップ可能な領域の定義 並び替え可能な要素の定義
ドラッグ機能 なし あり(内包している)
主な使用場面 ゴミ箱、追加ゾーンなど リストやボードの並び替え
関連コンテキスト 単体で利用可能 SortableContext が必須

よくあるケースと選択基準

  • 要素の順序を変更したい場合は useSortable
  • 特定エリアにドラッグ対象を受け入れたい場合は useDroppable
  • 並び替えつつ、リスト外のゴミ箱にドロップして削除する場合などは、両方を組み合わせて使用する