How can free layout dragging be implemented in React? Reactでのフリーレイアウトドラッグの実装方法は?
Reactでドラッグアンドドロップレイアウトを実装するには、HTML5のドラッグアンドドロップAPIを使用できます。以下は簡単な実装例です:
最初に、ドラッグ可能な要素を包装するDraggableコンポーネントを作成します。
import React from 'react';
const Draggable = ({ id, onDragStart, children }) => {
const handleDragStart = (event) => {
event.dataTransfer.setData('text/plain', id);
onDragStart(id);
};
return (
<div
draggable
onDragStart={handleDragStart}
style={{ cursor: 'move' }}
>
{children}
</div>
);
};
export default Draggable;
その後、親コンポーネントでコンテナ要素を作成し、ドラッグアンドドロップイベントを監視します。
import React, { useState } from 'react';
import Draggable from './Draggable';
const FreeLayout = () => {
const [draggedItem, setDraggedItem] = useState(null);
const [items, setItems] = useState([]);
const handleDrop = (event) => {
event.preventDefault();
const itemId = event.dataTransfer.getData('text/plain');
const newItem = { id: itemId, x: event.clientX, y: event.clientY };
setItems([...items, newItem]);
setDraggedItem(null);
};
const handleDragOver = (event) => {
event.preventDefault();
};
const handleDragStart = (itemId) => {
setDraggedItem(itemId);
};
return (
<div
onDrop={handleDrop}
onDragOver={handleDragOver}
style={{ width: '500px', height: '500px', border: '1px solid black' }}
>
{items.map((item) => (
<div
key={item.id}
style={{
position: 'absolute',
left: item.x,
top: item.y,
border: '1px solid red',
padding: '10px',
}}
>
{item.id}
</div>
))}
<Draggable id="item1" onDragStart={handleDragStart}>
Item 1
</Draggable>
<Draggable id="item2" onDragStart={handleDragStart}>
Item 2
</Draggable>
</div>
);
};
export default FreeLayout;
上記の例では、FreeLayoutコンポーネント内のstateは、ドラッグされた要素の位置情報を保存するために使用されます。また、Draggableコンポーネントはドラッグ可能な要素をカプセル化し、ドラッグが開始されるとコールバック関数がトリガーされます。
ドロップとドラッグオーバーイベントをコンテナ要素でリッスンし、ドロップイベントでドラッグした要素の情報を取得してstateに追加します。また、ドラッグした要素でdragstartイベントが発生したときに、その要素のIDをstateに保存します。
最後、stateの中の要素の位置情報に基づいてドラッグされた要素をレンダリングし、その位置を絶対位置に設定します。
これによって、シンプルなドラッグ&ドロップ自由配置が実現されました。必要に応じて拡張や最適化を行うことができます。