LoginSignup
25
20

More than 3 years have passed since last update.

React DnD が React hook で簡単に書けるようになっていた

Posted at

React で好きなように Drop & Drag の実装を書ける React DnD の API が解りにくかった (以前の API の把握は react-dnd これだけ抑えておけばおk がわかり易い)のだけど、最近のバージョンアップにより useDrag / useDrop 等の React hook が提供されていて(以前の API も Legacy Decorator API として残っている)、それらを使って簡単に書けるようになっていた。

例えばよくある List を Drag して、Drop 先の要素と swap する、の最小限の実装はこんな感じ。わりと型もちゃんと書ける。

import React, { useState, useCallback, useRef, FC } from "react"
import { useDrag, useDrop, DndProvider } from "react-dnd"
import Backend from "react-dnd-html5-backend"

const DND_GROUP = "list"

interface DragItem {
  type: string
  index: number
}

interface ListProps {
  index: number
  text: string
  swapList: (sourceIndex: number, targetIndex: number) => void
}

const List: FC<ListProps> = ({ index, text, swapList }) => {
  const ref = useRef<HTMLLIElement>(null)
  const [, drop] = useDrop({
    accept: DND_GROUP,
    drop(item: DragItem) {
      if (!ref.current || item.index === index) {
        return
      }
      swapList(item.index, index)
    }
  })
  const [, drag] = useDrag({
    item: { type: DND_GROUP, index }
  })
  drag(drop(ref))
  return <li ref={ref}>{text}</li>
}

const ListView = () => {
  const [list, setList] = useState(["foo", "bar", "baz", "hoge", "huga"])
  const swapList = useCallback(
    (sourceIndex: number, targetIndex: number) => {
      [list[targetIndex], list[sourceIndex]] = [list[sourceIndex], list[targetIndex]]
      setList(list.splice(0))
    },
    [list]
  )
  return (
    <ul>
      {list.map((text, index) => (
        <List key={index} text={text} index={index} swapList={swapList} />
      ))}
    </ul>
  )
}

const App: FC = () => {
  return (
    <DndProvider backend={Backend}>
      <ListView />
    </DndProvider>
  )
}

React DnD、チュートリアルで一通り学べるのだけど、題材がチェスの実装になっていて、どんな感じで Drag & Drop が実装できるのだろう、というところにたどり着くまでが長い…。

25
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
20