如何为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
相关产品推荐
相关产品推荐

