テーマ
- とあるReactアプリでドラッグ&ドロップで要素を伸び縮みさせるUIを作って欲しいという依頼があった
- これだけの要件であればreact-dndを使うと冗長そうなので、今回は使わずに自前で実装してみた
デモ
- 黒い部分をドラッグ&ドロップすると縦に伸び縮みします
See the Pen React Drag&Drop Resize by mikan3rd (@mikan3rd) on CodePen.
解説
draggable属性
- 要素がドラッグ可能であることを示すために
draggable={true}
が必要です
onDrag / onTouchMove
- ドラッグ中に発生し続けるイベントです
- onDragイベントはスマートフォン/タブレット端末には対応していないため、代わりにonTouchMoveイベントで代用しています
handleChangeHeightでやっていること
-
React.useRef()
を使い、targetRef
に伸び縮みさせる要素を渡すようにしています - ドラッグ中の位置(引数の
clientY
) と現在の要素の底の位置(getBoundingClientRect()
で取得したbottom
)の差分を計算し、現在の要素の高さと足し算することで次の要素の高さを算出します
-React.useState()
のstateでheightを更新すると再レンダリングが大量に発生して遅いため、targetRef.current.style.height
で直接高さを変更して伸び縮みさせるようにしています
onDragStart / dataTransfer.setDragImage()
- デフォルトだとドラッグ時にドラック中の要素がカーソルに合わせて薄く表示されるようになっています
- これは
onDragStart
時にdataTransfer.setDragImage()
で変更することができます - 非表示にしたい場合、
dataTransfer.setDragImage()
の引数にnull
などを指定することができないので、透明な画像を用意して指定しています
以上!
- 自分でUIを作ると色々勉強になりますね、皆さんもぜひ試してみてください!
- ちなみに
React.useRef()
は再レンダリング対象にさせたくない変数としても使えるので覚えておくと便利