当前位置:首页 > React

react拖拽实现

2026-01-26 11:28:23React

实现拖拽的基本步骤

安装依赖库react-dndreact-dnd-html5-backend

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

创建可拖拽组件需要使用useDrag钩子:

import { useDrag } from 'react-dnd';

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

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

创建放置区域

使用useDrop钩子实现放置区域:

import { useDrop } from 'react-dnd';

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

  return (
    <div ref={drop} style={{ backgroundColor: isOver ? 'lightgreen' : 'white' }}>
      放置区域
    </div>
  );
}

组合组件并管理状态

在父组件中管理拖拽状态:

react拖拽实现

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

function App() {
  const [items, setItems] = useState([...]);
  const [droppedItems, setDroppedItems] = useState([]);

  const handleDrop = (id) => {
    const item = items.find(i => i.id === id);
    setDroppedItems([...droppedItems, item]);
  };

  return (
    <DndProvider backend={HTML5Backend}>
      <div>
        {items.map(item => (
          <DraggableItem key={item.id} item={item} />
        ))}
        <DropZone onDrop={handleDrop} />
      </div>
    </DndProvider>
  );
}

高级自定义选项

实现自定义拖拽预览:

const [{ isDragging }, drag, preview] = useDrag(() => ({
  type: 'ITEM',
  item: { id },
}));

return (
  <>
    <div ref={preview} style={{ position: 'absolute', opacity: 0 }}>
      预览内容
    </div>
    <div ref={drag}>实际内容</div>
  </>
);

添加拖拽限制条件:

react拖拽实现

useDrop(() => ({
  accept: 'ITEM',
  canDrop: (item) => item.type === 'ALLOWED_TYPE',
  drop: (item) => {...},
}));

触摸设备支持

对于移动设备,需要安装react-dnd-touch-backend

npm install react-dnd-touch-backend

然后替换backend:

import { TouchBackend } from 'react-dnd-touch-backend';

<DndProvider backend={TouchBackend} options={{ enableMouseEvents: true }}>
  ...
</DndProvider>

性能优化建议

对于大量可拖拽项,使用useMemo优化:

const items = useMemo(() => data.map(item => (
  <DraggableItem key={item.id} item={item} />
)), [data]);

避免不必要的重渲染,将拖拽逻辑与展示组件分离。

标签: 拖拽react
分享给朋友:

相关文章

如何降低react版本

如何降低react版本

降低 React 项目版本的步骤 检查当前 React 版本 在项目根目录的 package.json 文件中查看 dependencies 或 devDependencies 下的 react 和…

react moment如何使用

react moment如何使用

安装 react-moment 通过 npm 或 yarn 安装 react-moment: npm install react-moment 或 yarn add react-moment 基本…

react如何部署

react如何部署

部署 React 应用的常见方法 使用静态服务器部署 React 应用在构建后会生成静态文件,可以直接通过静态服务器部署。常用的静态服务器包括 Nginx、Apache 等。 运行构建命令生成静态文…

react如何拓展

react如何拓展

React 拓展方法 使用高阶组件(HOC) 高阶组件是一种复用组件逻辑的方式,通过接收一个组件并返回一个新组件实现功能拓展。例如,为组件添加日志功能: function withLogging…

react 如何启动

react 如何启动

创建 React 项目 使用官方工具 create-react-app 快速初始化项目,需提前安装 Node.js(版本 ≥ 14.0.0)和 npm/yarn: npx create-react-…

react如何循环

react如何循环

循环渲染列表 在React中循环渲染列表通常使用map方法,这是最常用的方式。通过map可以将数组中的每个元素转换为React元素并渲染到页面上。 const items = ['Apple', '…