Getting Started of React Dnd

react-dnd

  • React でDrag and Drop可能なcomponentを構築するのに使うライブラリ

backend

  • HTML5のDrag and Drop APIをベースに実装
  • touch screenでは動作しないので、backendをpluggableにしてある

Item and Types

  • item: Dragされているアイテムはplane な JS オブジェクトで管理
  • type: reduxのtypeと似ている(雑)

    • どのdragSource / dragTargetがDnDできるのか指定できる

Monitor

  • DnDの状態を内部のストレージで管理して、propsに反映させる
  • collecction functionでどの

Connector

  • dom eventのハンドリングをするbackendとreactをつなぐ必要がある
  • renderメソッドでconnectorを使ってdom nodesに役割をアサインする

    • drag source / drag preview / drop target
  • collector functionの第1引数がconnector

    • propsに渡して、renderする

Drag sources / Drag targets

  • drag source でwrapすることで、draggableになる

    • drag sorucesはtypeが登録されている
    • component propsからitem をproduceするメソッドがないといけない
    • drag and drop のイベントハンドラーを指定できる
    • collecting functionを指定する
  • drop targetもdrag sourceと似ている

    • 1つのdrop targetでいくつかのitem typesを1度に登録する
    • itemをproduceする代わりにhoverかdropのイベントをハンドリングする

Hocの利用

  • DragSource / DragType classはHocになっている

    • component を受け取って、別のcomponentを返すやつ
  • draggableにしたいアイテムを引数にHocを利用する
import { DragSource } from 'react-dnd';

class YourComponent {
  /* ... */
}

export default DragSource(/* ... */)(YourComponent);
  • flowメソッドを利用して、DragSource / DropTarget の宣言をまとめることができる
import { DragSource, DropTarget } from 'react-dnd';
import flow from 'lodash/flow';

class YourComponent {
  render() {
    const { connectDragSource, connectDropTarget } = this.props
    return connectDragSource(connectDropTarget(
      /* ... */
    ))
  }
}

メモ

既存プロダクトで利用されてて、propsを見てDrag and Dropの on / off を切り替えたかった

  • DragSource componentで canDrag() メソッド実装するとよかった

    • canDrop メソッドの引数が props と monitor
    • collector function内で、canDrop propertyに、 monitor.canDrop() を設定する