Reactのドラッグ&ドロップ:並べ替えリストとカンバンボード
ホーム
Reactドラッグ&ドロップガイド
Reactのドラッグ&ドロップ:並べ替えリストとカンバン(dnd-kit)| We.Inc
dnd-kit、またはネイティブのHTMLドラッグイベントで、Reactの並べ替えリストとカンバンボードを作ります。ページ上で動くボード、キーボードでの移動、コピーできるコード付きです。
ほとんどのReactアプリでは、dnd-kitが最もシンプルで堅実な選択です。MITライセンスのツールキットで、ポインター、タッチ、キーボードのセンサーが組み込まれています。@dnd-kit/reactをインストールし、対象の領域をDragDropProviderで囲み、各カードにid、index、groupを指定したuseSortableを付けて、onDragEndで状態を更新します。ネイティブのHTMLドラッグイベントでも実現できますが、手書きのコードが増えます。
ドラッグ&ドロップを追加する2つの方法
dnd-kit(@dnd-kit/react) ネイティブのHTMLドラッグ&ドロップ
インストール npm install @dnd-kit/react 不要、ブラウザーに組み込み済み
キーボード キーボードセンサーを同梱 キー操作は自分で作る
タッチ タッチとポインターのセンサーを同梱 ブラウザーによって異なるため、スマートフォンで要テスト
並べ替えリスト @dnd-kit/react/sortableのuseSortable ドロップ時の処理で自分でインデックスを計算
向いている用途 カンバンボード、並べ替えリスト、グリッド ファイルのドロップや単純な単発のドロップ
下には、今すぐカードをドラッグして動かせる実際のボードがあり、マウスを使わない人のための矢印ボタンも付いています。その下には、同じ並べ替えリストと複数カラムのボードを作るdnd-kitのコードと、比較のためにブラウザーの素のイベントを使った版を載せています。
カードをカラム内でドラッグして並べ替えるか、別のカラムへドラッグして移動します。 マウスがない場合は、Tabキーでカードに移動し、移動ボタンで位置やカラムを変えます。 まずdnd-kitの並べ替えリストをコピーし、次にカラムごとにグループを追加したカンバン版をコピーします。 ボードのデータはカラムをキーにした普通の状態として持ち、次のコピーはonDragEndに作らせましょう。
ドラッグできる要素にはすべて、データ由来の安定したidを付けましょう。配列のインデックスをidにすると、項目が動いた瞬間に壊れます。 event.canceledがtrueなら早めに処理を抜けましょう。そうすれば、ドラッグ中にEscapeを押してもボードは変わりません。 ドロップ後に新しい順序をバックエンドに保存し、リクエストが失敗したら元に戻しましょう。 カードが着地する場所には見える隙間か枠線を残しましょう。人は手を離す前に行き先を確認したいものです。 空のカラムにもある程度の高さを持つドロップ領域が必要です。そうしないと何もドロップできなくなります。
よくある質問
react-beautiful-dndは今でもよい選択ですか?
Atlassianはreact-beautiful-dndのリポジトリをアーカイブし、後継のPragmatic drag and dropを推奨しています。新しくReactで作るなら、活発にメンテナンスされている選択肢としてdnd-kitとPragmatic drag and dropを比較しましょう。
@dnd-kit/coreと@dnd-kit/reactの違いは何ですか?
@dnd-kit/coreと@dnd-kit/sortableは、長く使われてきたReact用のパッケージの組み合わせです。@dnd-kit/reactは、フレームワークに依存しないコアの上に作られた新しいアダプターで、そのコアはVue、Svelte、Solidのアダプターも支えています。新しいコードは、現在のドキュメントと同じく@dnd-kit/reactから始められます。
HTMLのAPIでdropイベントが発生しないのはなぜですか?
ドロップ先は、dragoverのハンドラーでevent.preventDefault()を呼ぶ必要があります。この呼び出しがないと、ブラウザーはその要素を無効な行き先とみなし、dropイベントは送られません。
ドラッグ&ドロップをアクセシブルにするには?
各カードをフォーカス可能にし、キーボードで持ち上げ、移動し、ドロップする方法を用意して、結果をライブリージョンで読み上げます。dnd-kitにはキーボードセンサーとアクセシビリティ対応が最初から含まれています。ネイティブのAPIでは、すべて自分で追加します。
まず状態、ドラッグはその次
ボードは配列を持つオブジェクトで、カラムごとにカードidの配列が1つあります。ドラッグが決めるのは、どのカードが動いたか、どこから来たか、どこに着地したかだけです。どのライブラリもこの4つの情報を渡してくれ、あなたのコードがそれを新しいオブジェクトに変えます。 この移動処理は純粋なヘルパー関数として書き、ブラウザーなしでテストしましょう。dnd-kitには@dnd-kit/helpersのmoveという関数まで用意されていて、項目とドラッグイベントを受け取り、更新したコピーを返します。
ネイティブのAPIが見た目より難しい理由
ブラウザーは7つのイベント(dragstart、drag、dragenter、dragleave、dragover、drop、dragend)を発生させ、有効なすべての行き先でdragoverをキャンセルする必要があります。データは文字列としてevent.dataTransferで運ばれ、読めるのはdropのハンドラーの中だけです。 キーボードでの操作手段はなく、他のカードをアニメーションでよける組み込みの方法もありません。アップロード領域にファイルをドロップするだけなら問題ありませんが、並べ替えボードはすぐに小さな自作ライブラリのように膨らみます。
dnd-kitで作る並べ替えリスト
npm install @dnd-kit/reactでインストールします。各項目は自分のインデックスを把握しており、ドロップ後はsource.initialIndexとsource.indexで移動元と移動先がわかります。
SortableList.jsx
タスク名の配列を並べ替えます。コピーしてからspliceするので、元の状態はそのまま保たれます。
dnd-kitで作るカンバンボード
useSortableにgroupを追加すると、カードがカラム間を移動できるようになります。source.initialGroupとsource.groupが、移動前と移動後のカラム名です。
KanbanBoard.jsx
3つのカラムを1つのオブジェクトで保持します。カラム内の移動では並べ替え、カラムをまたぐ移動ではカードを一方の配列から取り除いてもう一方に挿入します。
ネイティブのHTMLドラッグイベントで同じことをする
パッケージは不要です。onDragOverのpreventDefaultに注意してください。これがないとdropが発生しません。
NativeColumns.jsx
ドロップされたカラムの末尾にカードを移動します。カラム内での並べ替えには、インデックスの処理を追加する必要があります。
HTMLドラッグイベントのリファレンス
7つのドラッグイベントと発生する場所
ドラッグされる要素 ドラッグの開始時。ここでdataTransferを設定
行き先の候補 上にある間繰り返し。ドロップを許可するにはpreventDefaultを呼ぶ
行き先 有効な行き先で項目が離されたとき。ここでdataTransferを読む
ドラッグされる要素 ドラッグの終了時(ドロップまたはキャンセル)
未着手
進行中
完了
ロゴ
料金表
お問い合わせフォーム
ヒーローセクション
ドメイン
{card}を{column}の{n}番目に移動しました
試してみよう:動くカンバンボード
カードを未着手、進行中、完了の間でドラッグするか、各カードの移動ボタンを使ってください。
{column}カラム
{card}を上へ移動
{card}を下へ移動
{card}を{column}へ移動
前のカラム
次のカラム
ボードをリセットしました
ボードをリセット
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る