【React】ドラッグアンドドロップのやり方

React

Reactでドラッグアンドドロップする方法を紹介します。

Reactでドラッグアンドドロップする方法

ライブラリを使用します。
いくつかありますが、見た目がリッチになって使いやすいreact-beautiful-dndというライブラリを使用します。
このライブラリはReactのバージョン18で使うには、問題点があるため、合わせて【React】V18でreact-beautiful-dnd(ドラッグアンドドロップライブラリ)を使う方法 も確認してみてください。
ReactのV17なら問題なく動作します。

App.jsに以下を記述

import "./App.css";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import { useState } from "react";

function App() {
  const [items] = useState([
    { id: 1, text: "item1" },
    { id: 2, text: "item2" },
    { id: 3, text: "item3" },
    { id: 4, text: "item4" },
    { id: 5, text: "item5" },
  ]);

  const onDragEnd = (result) => {
    // console.log('発火');
    // drag時のindexの値
    // console.log(result.source.index);
    // drag終了後のindexの値
    // console.log(result.destination.index);

    const remove = items.splice(result.source.index, 1);
    items.splice(result.destination.index, 0, remove[0]);
  };
  return (
    <div className="dragDropArea">
      {/* DragDropContextだけdrag and dropできる */}
      {/* onDragEndはdrag終了時に発火する */}
      <DragDropContext onDragEnd={onDragEnd}>
        {/* Droppableはidが必要 */}
        {/* DroppableとDraggableの子供は関数でないとエラーになる(divタグとかじゃだめ) */}
        <Droppable droppableId="droppable">
          {(provided) => (
            // droppablePropsというプロパティとrefが必要
            // <div {...provided.droppableProps} ref={provided.innerRef}>部分はお決まりのライブラリのお作法として記述が必要
            <div {...provided.droppableProps} ref={provided.innerRef}>
              {/* Draggableもidが必要 */}
              {/* index={0}は何番目のdraggable要素かを識別するためのもので必要 */}
              {items.map((item, index) => (
                <Draggable draggableId={item.text} index={index} key={item.id}>
                  {/* Droppableで指定した引数をそのまま指定する */}
                  {(provided) => (
                    // この中で静的なdivタグなどを指定できる
                    //  <div {...provided.draggableProps} ref={provided.innerRef}>もお作法
                    // 実際に掴んで移動させるpropsに{...provided.dragHandleProps}をつける
                    <div
                      className="item"
                      {...provided.draggableProps}
                      ref={provided.innerRef}
                      {...provided.dragHandleProps}
                    >
                      {item.text}
                    </div>
                  )}
                </Draggable>
              ))}
              {/* placeholderは領域広げる、ないとコンソールにエラーでる */}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </div>
  );
}

export default App;

必ず必要なものに以下があります。

インポート

import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";

DragDropContextの中に、Droppableを入れて、さらにその中にDraggableを入れることで、Draggableコンポーネントをドラッグアンドドロップすることができるようになります。

onDragEndメソッド

  const onDragEnd = (result) => {
    // console.log('発火');
    // drag時のindexの値
    // console.log(result.source.index);
    // drag終了後のindexの値
    // console.log(result.destination.index);

    const remove = items.splice(result.source.index, 1);
    items.splice(result.destination.index, 0, remove[0]);
  };

onDragEndメソッドは、drag終了時に発火する関数になります。
result部分にいろいろな情報が入るのですが、階層が深いため、重要な部分だけを取り出すと、
result.source.indexが、drag時のindexの値が保持されているプロパティになります。
そして、result.destination.indexがdrag終了後のindexの値が保持されているプロパティです。

そして、spliceを使って、動かしたものを削除して、それを変数(remove)に格納します。
そして、その変数を動かした場所に入れることで、ドラッグアンドドロップの動きができるようになります。

{…provided.droppableProps} ref={provided.innerRef}あたりの記述について

難しいので、ライブラリを使うときに必ず必要なお作法と思っておけばいいです。

{…provided.dragHandleProps}について

Draggableコンポーネント内の実際にドラッグアンドドロップする要素に対して設定します。
これをつけることで、ドラッグアンドドロップできるようになります。

{provided.placeholder}について

placeholderは領域広げるための記述です。
ないとコンソールにエラーでるので、これもお作法として記述が必要になります。

React

Posted by devsakaso