当前位置:首页 > React

react如何实现拖拽布局

2026-03-11 04:47:57React

实现拖拽布局的核心方法

React 中实现拖拽布局通常需要借助第三方库,以下是几种主流方案及其实现方式:

使用 react-dnd

react-dnd 是 React 生态中功能强大的拖拽库,适合复杂场景。

安装依赖:

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

基础代码结构:

import { DndProvider, useDrag, useDrop } 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 = ({ children }) => {
  const [{ canDrop }, drop] = useDrop(() => ({
    accept: 'ITEM',
    drop: () => ({ name: 'DropZone' }),
    collect: (monitor) => ({
      canDrop: !!monitor.canDrop(),
    }),
  }));

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

const App = () => (
  <DndProvider backend={HTML5Backend}>
    <DropZone>
      <DraggableItem id="1" text="Drag me" />
    </DropZone>
  </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' },
];

const App = () => {
  const [list, setList] = useState(items);

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

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="droppable">
        {(provided) => (
          <div ref={provided.innerRef} {...provided.droppableProps}>
            {list.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

适合简单场景,无需额外依赖。

实现示例:

react如何实现拖拽布局

const DraggableComponent = () => {
  const handleDragStart = (e) => {
    e.dataTransfer.setData('text/plain', e.target.id);
  };

  const handleDrop = (e) => {
    e.preventDefault();
    const id = e.dataTransfer.getData('text');
    const draggable = document.getElementById(id);
    e.target.appendChild(draggable);
  };

  const handleDragOver = (e) => {
    e.preventDefault();
  };

  return (
    <div>
      <div
        id="drag-item"
        draggable
        onDragStart={handleDragStart}
        style={{ width: '100px', height: '100px', background: 'red' }}
      />
      <div
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        style={{ width: '200px', height: '200px', border: '1px dashed black' }}
      />
    </div>
  );
};

性能优化建议

  • 对于大型列表,使用 react-windowreact-virtualized 进行虚拟滚动
  • 避免在拖拽过程中频繁更新状态
  • 使用 CSS transform 代替 top/left 定位以减少重排

选择依据

  • 简单拖放:原生 HTML5 API
  • 列表排序:react-beautiful-dnd
  • 复杂交互:react-dnd
  • 跨框架需求:dnd-kit(较新的替代方案)

分享给朋友:

相关文章

vue项目如何实现

vue项目如何实现

安装Vue.js 通过npm或yarn安装Vue.js。确保Node.js环境已配置完成。 npm install vue # 或 yarn add vue 创建Vue项目 使用Vue CLI工具快…

如何实现java序列化

如何实现java序列化

实现Java序列化的方法 1. 实现Serializable接口 要使一个类可序列化,需要让该类实现java.io.Serializable接口。这是一个标记接口,没有任何方法需要实现。 publi…

React如何实现通知

React如何实现通知

React 实现通知的方法 使用状态管理 在 React 组件中通过 useState 或 useReducer 管理通知状态,触发状态更新时显示通知。适合简单场景,无需额外依赖。 import {…

vue页面布局实现

vue页面布局实现

Vue 页面布局实现方法 基础布局结构 使用 Vue 单文件组件(SFC)构建页面框架,结合 <template>、<script> 和 <style> 三个部分。…

vue 如何实现返回

vue 如何实现返回

Vue 实现返回功能的方法 使用 router.go(-1) 在 Vue 中可以通过 Vue Router 的 go 方法实现返回上一页的功能。在需要触发返回的按钮或方法中调用 this.$route…

Vue实现拖拽布局

Vue实现拖拽布局

Vue 实现拖拽布局的方法 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 dr…