当前位置:首页 > React

拖拽react组件实现

2026-01-27 00:25:46React

实现拖拽React组件的核心方法

使用React DnD库 React DnD是一个流行的拖放库,专为React设计。安装依赖包:

npm install react-dnd react-dnd-html5-backend

基础实现示例:

import { useDrag, useDrop, DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

const DraggableItem = ({ id, text }) => {
  const [{ isDragging }, drag] = useDrag(() => ({
    type: 'ITEM',
    item: { id },
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging(),
    }),
  }));

  return (
    <div ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
      {text}
    </div>
  );
};

const DropZone = ({ onDrop }) => {
  const [{ canDrop }, drop] = useDrop(() => ({
    accept: 'ITEM',
    drop: (item) => onDrop(item.id),
    collect: (monitor) => ({
      canDrop: !!monitor.canDrop(),
    }),
  }));

  return (
    <div ref={drop} style={{ background: canDrop ? 'lightgreen' : 'white' }}>
      Drop here
    </div>
  );
};

const App = () => (
  <DndProvider backend={HTML5Backend}>
    <DraggableItem id={1} text="Drag me" />
    <DropZone onDrop={(id) => console.log(`Dropped item ${id}`)} />
  </DndProvider>
);

使用react-beautiful-dnd库 适用于列表重排序场景。安装:

npm install react-beautiful-dnd

列表拖拽示例:

import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

const items = [{id: '1', content: 'Item 1'}, {id: '2', content: 'Item 2'}];

function App() {
  const [state, setState] = useState(items);

  const onDragEnd = (result) => {
    if (!result.destination) return;
    const newItems = Array.from(state);
    const [removed] = newItems.splice(result.source.index, 1);
    newItems.splice(result.destination.index, 0, removed);
    setState(newItems);
  };

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="droppable">
        {(provided) => (
          <div {...provided.droppableProps} ref={provided.innerRef}>
            {state.map((item, index) => (
              <Draggable key={item.id} draggableId={item.id} index={index}>
                {(provided) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                  >
                    {item.content}
                  </div>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
}

原生HTML5拖拽API实现 不需要额外依赖的基础方案:

function Draggable() {
  const dragStart = (e) => {
    e.dataTransfer.setData('text/plain', e.target.id);
    e.target.style.opacity = '0.4';
  };

  const dragEnd = (e) => {
    e.target.style.opacity = '1';
  };

  return (
    <div
      id="draggable-item"
      draggable="true"
      onDragStart={dragStart}
      onDragEnd={dragEnd}
    >
      Drag me
    </div>
  );
}

function DropZone() {
  const allowDrop = (e) => e.preventDefault();

  const drop = (e) => {
    e.preventDefault();
    const data = e.dataTransfer.getData('text');
    e.target.appendChild(document.getElementById(data));
  };

  return (
    <div onDrop={drop} onDragOver={allowDrop}>
      Drop here
    </div>
  );
}

关键注意事项

性能优化 对于大量可拖拽项目,使用shouldComponentUpdate或React.memo避免不必要的渲染。react-beautiful-dnd内置了虚拟列表支持。

触摸设备支持 HTML5 API在移动端支持有限,React DnD需要通过touch-backend替代默认后端:

import { TouchBackend } from 'react-dnd-touch-backend';
<DndProvider backend={TouchBackend} options={{ enableMouseEvents: true }}>

状态管理 拖拽操作通常需要与全局状态同步,建议结合Redux或Context API管理拖拽状态。

视觉反馈 通过useDrag/useDrop的collect函数或react-beautiful-dnd的provided props实现拖拽过程中的样式变化,增强用户体验。

无障碍支持 添加ARIA属性确保屏幕阅读器可访问:

拖拽react组件实现

<div
  role="button"
  aria-grabbed={isDragging}
  tabIndex={0}
>

标签: 组件拖拽
分享给朋友:

相关文章

vue实现组件

vue实现组件

Vue 组件实现基础 Vue 组件是可复用的 Vue 实例,用于封装 UI 和逻辑。通过 .vue 文件或直接注册组件实现。 单文件组件 (SFC) 示例 <template>…

vue实现倒计时组件

vue实现倒计时组件

Vue 倒计时组件实现 核心思路 通过 setInterval 或 setTimeout 实现时间递减,结合 Vue 的响应式数据更新 UI。需注意组件销毁时清除定时器。 基础实现方案 模板部分…

实现vue组件

实现vue组件

创建 Vue 组件 Vue 组件可以通过单文件组件(.vue 文件)或直接在 JavaScript 中定义。以下是两种常见实现方式。 单文件组件方式 单文件组件包含模板、脚本和样式三部分,适合复杂项…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

uniapp组件写法

uniapp组件写法

Uniapp 组件的基本写法 Uniapp 的组件写法与 Vue 类似,支持单文件组件(.vue 文件)。一个基本的组件通常包含三个部分:<template>、<script>…

vue实现广告组件

vue实现广告组件

vue实现广告组件的方法 使用动态组件实现 在Vue中可以通过动态组件的方式加载广告组件,根据不同的条件展示不同的广告内容。动态组件使用<component :is="currentCompon…