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

如何为MaterialUI免费版x-data-grid添加行拖拽排序功能?

问题描述

尝试为x-data-grid组件实现行排序功能但未成功,页面能显示行但无法拖拽,无效代码如下:

<DragDropContext onDragEnd={handleDragEnd}>
    <Droppable droppableId="rows">
        {(provided, snapshot) => (
            <div ref={provided.innerRef} {...provided.droppableProps}>
                <DataGrid
                    rows={rows}
                    columns={columns}
                    components={{
                        Row: ({ index, style, ...rest }) => (
                            <Draggable draggableId={index.toString()} index={index}>
                                {(provided, snapshot) => {
                                    return <div
                                             ref={provided.innerRef}
                                             {...provided.draggableProps}
                                             {...provided.dragHandleProps}>
                                              <GridRow {...rest} />
                                            </div>
                                 }}
                             </Draggable>
                             ),
                      }}
                   />
                {provided.placeholder}
           </div>
       )}
    </Droppable>
</DragDropContext>

请问该功能是否可实现?若可以,请给出实现说明。


实现方案

该功能完全可以实现,你的代码存在几个关键问题,修正后即可正常拖拽排序:

核心问题与修复点

  • Draggable标识错误:不能用index作为draggableId,行顺序变化时index会同步改变,导致拖拽组件的唯一标识混乱,必须使用每行数据自带的稳定唯一ID(比如row.id)。
  • 样式参数未传递:原代码中Row组件的style参数未传给GridRow,会导致拖拽时行的位置计算异常。
  • 缺少拖拽状态更新逻辑:onDragEnd回调内没有实现行顺序的更新逻辑,拖拽后无法同步数据状态。
  • 未适配虚拟滚动:DataGrid默认使用虚拟滚动,需给Droppable添加mode="virtual"属性,避免渲染异常。

完整可运行代码

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

// 拖拽结束后更新行顺序
const handleDragEnd = (result, rows, setRows) => {
  if (!result.destination) return;

  const newRows = Array.from(rows);
  const [movedRow] = newRows.splice(result.source.index, 1);
  newRows.splice(result.destination.index, 0, movedRow);

  setRows(newRows);
};

// 自定义可拖拽行组件
const DraggableRow = ({ row, index, style, ...rest }) => (
  <Draggable draggableId={row.id.toString()} index={index}>
    {(provided) => (
      <div
        ref={provided.innerRef}
        {...provided.draggableProps}
        style={{ ...style, ...provided.draggableProps.style }}
      >
        {/* 可自定义拖拽手柄,比如添加图标 */}
        <span {...provided.dragHandleProps} style={{padding: '0 8px', cursor: 'grab'}}>⋮⋮</span>
        <GridRow {...rest} />
      </div>
    )}
  </Draggable>
);

// 主组件
const SortableDataGrid = ({ rows, columns, setRows }) => (
  <DragDropContext onDragEnd={(result) => handleDragEnd(result, rows, setRows)}>
    <Droppable droppableId="data-grid-rows" mode="virtual">
      {(provided) => (
        <div ref={provided.innerRef} {...provided.droppableProps}>
          <DataGrid
            rows={rows}
            columns={columns}
            rowHeight={56}
            components={{ Row: DraggableRow }}
            disableRowSelectionOnClick
          />
          {provided.placeholder}
        </div>
      )}
    </Droppable>
  </DragDropContext>
);

额外注意事项

  • 确保每行数据都有稳定的唯一ID字段,禁止用动态变化的index作为标识。
  • 若使用MUI X DataGrid Pro版本,可直接使用官方内置的rowReorder功能,无需手动集成react-beautiful-dnd。
  • 拖拽手柄可自定义样式,提升用户操作的直观性。

内容的提问来源于stack exchange,提问作者Hasan Baki Kucukcakiroglu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 01:57:37