You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Beautiful DnD集成MUI X Data Grid行拖拽失效,如何正确实现?

MUI X DataGrid 集成 React Beautiful DnD 行拖拽问题排查与修复

你的实现中存在的核心问题

  • 错误使用未定义的Grid.Row和Grid.Cell组件:MUI X DataGrid的自定义Row组件无需手动渲染单元格,应复用原Row的结构,否则会破坏DataGrid内部布局与事件传递。
  • Droppable与DataGrid层级冲突:将Droppable放在DataGrid外部,导致拖拽事件被DataGrid内部容器拦截,React Beautiful DnD无法捕获拖拽动作。
  • 自定义Row未正确传递原生props:未将DataGrid Row的样式、事件等原生props传递给根元素,导致拖拽触发失败。

修正后的完整代码

import React, { useState } from "react";
import { DataGrid } from "@mui/x-data-grid";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";

const columns = [
  { field: "id", headerName: "ID", width: 90 },
  { field: "name", headerName: "Name", width: 150 },
  { field: "age", headerName: "Age", width: 90 },
];

let initialRows = [
  { id: "1", name: "John Doe", age: 30 },
  { id: "2", name: "Jane Smith", age: 25 },
  { id: "3", name: "Bob Brown", age: 35 },
];

const CustomRow = ({ row, index, ...props }) => {
  return (
    <Draggable draggableId={`row-${row.id}`} index={index}>
      {(provided, snapshot) => (
        <div
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          style={{
            ...props.style,
            ...provided.draggableProps.style,
            backgroundColor: snapshot.isDragging ? "#f0f0f0" : "inherit",
            cursor: "move",
          }}
        >
          {props.children}
        </div>
      )}
    </Draggable>
  );
};

const CustomDataGrid = () => {
  const [rows, setRows] = useState(initialRows);

  const onDragEnd = (result) => {
    if (!result.destination) return;

    // 重新排序行数据
    const reorderedRows = Array.from(rows);
    const [movedRow] = reorderedRows.splice(result.source.index, 1);
    reorderedRows.splice(result.destination.index, 0, movedRow);

    setRows(reorderedRows);
  };

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="data-grid" mode="virtual">
        {(provided) => (
          <div ref={provided.innerRef} {...provided.droppableProps}>
            <DataGrid
              rows={rows}
              columns={columns}
              components={{
                Row: CustomRow,
              }}
              componentsProps={{
                row: {
                  // 传递行索引给自定义Row
                  index: (params) => params.index,
                },
              }}
              disableRowSelectionOnClick
              autoHeight
            />
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
};

export default CustomDataGrid;

关键修复说明

  1. 正确自定义Row组件:

    • 复用DataGrid原生Row的children(已渲染的单元格),保留原有布局;
    • 将Draggable的innerRef、draggableProps、dragHandleProps绑定到Row根div,确保拖拽事件被捕获;
    • 合并原生样式与拖拽组件样式,避免布局错乱。
  2. 适配虚拟滚动模式:

    • 给Droppable添加mode="virtual",适配DataGrid默认的虚拟滚动逻辑,避免拖拽时布局偏移。
  3. 传递行索引:

    • 通过componentsProps.row.index将DataGrid行索引传递给自定义Row,确保Draggable的index参数准确。
  4. 实现排序逻辑:

    • 在onDragEnd中重新排序行数据并更新state,完成拖拽后的持久化展示。
  5. 避免事件冲突:

    • 添加disableRowSelectionOnClick属性,防止拖拽时触发行选择事件干扰操作。

内容的提问来源于stack exchange,提问作者tarun pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:14:55