【React入門】react-draggableの使い方や他のライブラリとの比較について詳しく解説!

  • 2020年12月20日
  • 2024年4月7日
  • React

こんにちは、フロントエンドエンジニアのてりーです。
僕の詳しいプロフィールはこちら

・react-draggableとは?
・【基礎】react-draggableのドラッグ&ドロップの使い方
・【応用】react-draggableでクリックイベントの追加方法

Reactの基礎が不安な方へ

こちらの記事で学習の手順や教材について詳しく解説しています。

関連記事

こんにちは、フロントエンドエンジニアのてりーです。 僕がフロントエンドエンジニアとして、React + TypeScriptで開発して、3年ぐらい経過しました。 ノウハウがたまってきたので、React + TypeScriptの勉強[…]

では、どうぞ

react-draggableとは?

GitHub

React draggable component. Contribute to react-grid-layout/r…

Reactでドラッグ&ドロップを実現する為のライブラリです。

ドラッグ&ドロップの基本的な動きは全て網羅されていて、既存のコンポーネントをラップするだけで簡単に使えます!

他のライブラリとの比較

2024年現在でreact-drqaggbleのライバルになりそうなのは、この辺りですかね。

  • react-dnd
  • react-beautiful-dnd

僕の勤め先ではreact-dndを使っています。

人気度

npm trendsで直近2年間のダウンロード数を見ると、react-draggableが1位です!

5年前ぐらいから去年までは圧倒的なシェアを誇っていましたが、現在は他の2つとそこまで大差はなさそうです!

この図から読み取れる事として以下です。

・既存のプロジェクトではreact-draggableが使われている可能性が高
・新規でドラッグ&ドロップライブラリを導入する際は、どれも人気度に差はないので、特徴からプロジェクトにあったものを選ぶべき

    特徴

    react-draggable

    コンポーネントをラップするだけでドラッグ&ドロップが可能になる為、導入がとても簡単!

    そして基本的なドラッグ&ドロップの機能は全て備わっている。
    CSS Transformsを使う為、既に適応さえている場合は上書きされる点が注意が必要。

    react-dnd

    HTML5のドラッグ&ドロップAPIを基に構築されている為、より複雑なドラッグ&ドロップが実現出来る。

    UIコンポーネントが提供されていないので、他のライブラリに比べて理解に時間がかかるが、その分、汎用性が高く機能追加などに長く耐えうる。

    react-beautiful-dnd

    リスト内のアイテムのドラッグ&ドロップに特化している。
    逆にリストにしか使えない点が注意が必要!
    ライブラリの名前にもある通り、美しいUIが特徴!

    react-draggable:一般的なプロジェクトならコレ!使いやすく基本的な機能が網羅されている
    react-dnd:複雑なドラッグ&ドロップ操作が求められるプロジェクトならコレ!
    react-beautiful-dnd:業務システムなどリストアイテムでのみD&Dを使うならコレ!
    さて、ここからはreact-draggableを使って実例を見ていきましょう!!

    【基礎】react-draggableのドラッグ&ドロップの使い方

    実際のコードを見ながら解説していきます!

    以下のように、アイテムが画自由にドラッグ&ドロップ出来る状態を目指します!

    まずreact-draggableを使う前のコンポーネントがこちらです。

    export const Piece = () => {  
      return ( 
        <div> 
          <span>アイスクリーム</span> 
        </div>  
      ); 
    };

    1. ドラッグしたい要素を<Draggable>でラップする

    export const Piece = () => {
      return (
    
      // Draggableで要素をラップする
      <Draggable>
        <div>
          <span>アイスクリーム</span>
        </div>
      </Draggable>
      );
    };

    もうこれだけで、ドラッグアンドドロップ可能になりました!!

    めちゃくちゃ簡単でしょ!!

    【応用】react-draggableでクリックイベントの追加方法

    次はクリックイベントを追加していきます。
    先ほどのアイスクリームがクリックした際に回転するようにしましょう!!

    重要なのはドラッグ&ドロップでは回転せず、アイテムをクリックした時のみ回転する!ことです。

    こんな感じですね。

     

    やる事は以下です!

    1. onStopでクリック時に回転する処理を追加
    2. onDragでドラッグとクリックを判別する

    onStopだけではクリック時+ドラッグ終了時に回転してしまうので、onDragでドラッグ中の判定をして、ドラッグ終了時の回転を防いでいます。

    ではやっていきましょう!

    1. onStopでクリック時に回転する処理を追加

    今回はonStopを用いています。

    理由はonStopでクリック時のアクションを実装する事で、スマホなどのタッチ操作にも対応出来るからです!

    以下のissueにてシングルクリックを検出する方法について議論されています。

    GitHub

    I have a use-case in which the draggable element can either …

    onStopだけだとクリック時と、ドラッグ終了時の両方で回転してしまうので、後ほどonDragにてドラッグ終了時を判別出来るようにします。

    コード

    export const Piece = () => {
      // useStateで回転の角度を設定する
      const [currentRotate, setCurrentRotate] = useState(0);
    
      const onStop = () => {
        setCurrentRotate(currentRotate + 90);
      };
    
      return (
        <Draggable onStop={onStop}>
        // styleで回転を要素に反映
          <div style={{ transform: "rotate(" + currentRotate + "deg)" }}>
            <span>アイスクリーム</span>
          </div>
        </Draggable>
      );
    };

    これにて、ドラッグ終了時とクリック時に要素が回転するようになったかと思います。

    2. onDragでドラッグとクリックを判別する

    onDragを使いドラッグを検知する事で、onStopでのドラッグ終了時の回転を防いでいきます。

    まずはコードを見ていきましょう!

    export const Piece = () => {
      const [currentRotate, setCurrentRotate] = useState(0);
    
      // ①ドラッグ中か否かをuseRefで持つ
      const isDraggingRef = useRef(false);
    
      // ②onDragにてisDraggingRef.current = trueを返す
      const onDrag = () => {
        isDraggingRef.current = true;
      };
    
      // ③onStopにisDraggingRefの条件分岐を入れる
      const onStop = () => {
       if(!isDraggingRef.current){
           setCurrentRotate(currentRotate + 90);
          };
          isDraggingRef.current = false;
      };
    
      return (
        <Draggable onStop={onStop} onDrag={onDrag}>
          <div style={{ transform: "rotate(" + currentRotate + "deg)" }}>
             <span>アイスクリーム</span>
          </div>
        </Draggable>
      );
    };

    順を追って解説していきます!

    ①ドラッグ中か否かをuseRefで持つ

    ここではuseRefにてドラッグ中か否かの値を管理しています。
    onStopにて参照したいだけなので、再描画など複雑な観点はいらないのでuseRefを使っています。

    Qiita

    はじめに本記事は、ReactのuseRefについて紹介する入門的記事です。公式に書いてある内容の焼き直しみたいな物なので…

    ②onDragにてisDraggingRef.current = trueを返す

    onDragはドラッグで座標の移動が発生した時に発火します!
    ですので、isDragingRef.current = trueを返しましょう!

    要素が座標移動した = ドラッグであり、クリックじゃない!という判定です。

    onStopにisDraggingRefの条件分岐を入れる

    クリックとドラッグをisDraggingRedで管理できた所で、onStopに条件分岐を加えましょう!

    これにて完成です!

    まとめ

    react-draggableの基本情報や、使い方は理解出来たでしょうか?

    僕は普段からReact関連の発信をしているので、良かったら他の記事もご覧になって下さい。

    ReactかVue.sjのどちらをメインするかで迷ってる方へ
    関連記事

    読者 ・エンジニアになりたいけど、どの言語を学ぶか迷っている ・React、Vue.sjのどちらを学ぶか迷ってる ・将来性や年収も知りたい てりー そんな疑問に対して、解説します。 […]

    Reactを実務レベルまでマスターする勉強法
    関連記事

    こんにちは、フロントエンドエンジニアのてりーです。 僕がフロントエンドエンジニアとして、React + TypeScriptで開発して、3年ぐらい経過しました。 ノウハウがたまってきたので、React + TypeScriptの勉強[…]

    フロントエンドでキャリアアップを考えているなら
    関連記事

    こんにちは、フロントエンドエンジニアのてりーです。 僕の詳しいプロフィールはこちら 今回は大学中退してニートだった自分が完全未経験からメガベンチャーに入社した方法について解説していきます。 ・完全未経験から将来的なメガベンチャー転[…]