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

React Data Grid行拖拽与列重排联用问题求助

解决React Data Grid行拖拽+列重排的双重问题

我帮你排查下这个问题,看起来你遇到的onHeaderDrop不触发+id未定义报错是关联的,核心原因是列配置缺失必要属性、组件嵌套顺序不对导致的,下面是具体的解决方案:

首先,Cannot read property 'id' of undefined的报错直接指向你的列配置里没有给每个列设置唯一的id属性——React Data Grid处理列拖拽重排时,必须依赖列的id来识别列并更新顺序,缺失这个属性就会抛出错误,进而导致onHeaderDrop事件无法正常触发。

其次,行拖拽和列重排的组件嵌套顺序也有误,正确的嵌套应该是用列重排的DraggableHeader.DraggableContainer包裹行拖拽的Draggable.Container,而不是反过来。

下面是修改后的完整示例代码,基于你提到的example23-row-reordering.js调整,可同时实现行拖拽和列重排:

const ReactDataGrid = require('react-data-grid');
const exampleWrapper = require('../components/exampleWrapper');
const React = require('react');
const {
  Draggable: { Container: DraggableRowContainer, RowActionsCell },
  DraggableHeader: { DraggableContainer: DraggableColumnContainer },
  Data: { Selectors }
} = require('react-data-grid-addons');

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rows: this.createRows(100),
      columns: [
        // 关键:每个列必须设置唯一的id属性
        { key: 'id', name: 'ID', id: 'id', width: 80 },
        { key: 'title', name: 'Title', id: 'title', width: 200, draggable: true },
        { key: 'count', name: 'Count', id: 'count', width: 100, draggable: true },
        { key: 'actions', name: 'Actions', id: 'actions', width: 120, cellClass: 'actions-cell', renderer: RowActionsCell }
      ]
    };
  }

  createRows = (numberOfRows) => {
    let rows = [];
    for (let i = 1; i <= numberOfRows; i++) {
      rows.push({
        id: i,
        title: `Task ${i}`,
        count: Math.floor(Math.random() * 100)
      });
    }
    return rows;
  };

  handleRowDrop = (sourceRowIndex, targetRowIndex) => {
    const { rows } = this.state;
    const updatedRows = Selectors.moveRow(rows, sourceRowIndex, targetRowIndex);
    this.setState({ rows: updatedRows });
  };

  handleHeaderDrop = (sourceColumnIndex, targetColumnIndex) => {
    const { columns } = this.state;
    // 手动调整列数组顺序,更新列配置
    const updatedColumns = [...columns];
    const [movedColumn] = updatedColumns.splice(sourceColumnIndex, 1);
    updatedColumns.splice(targetColumnIndex, 0, movedColumn);
    this.setState({ columns: updatedColumns });
  };

  render() {
    const { rows, columns } = this.state;
    return (
      // 正确嵌套:列重排容器包裹行拖拽容器
      <DraggableColumnContainer onHeaderDrop={this.handleHeaderDrop}>
        <DraggableRowContainer onRowDrop={this.handleRowDrop}>
          <ReactDataGrid
            columns={columns}
            rowGetter={i => rows[i]}
            rowsCount={rows.length}
            minHeight={500}
          />
        </DraggableRowContainer>
      </DraggableColumnContainer>
    );
  }
}

module.exports = exampleWrapper({
  component: Example,
  exampleName: 'Row and Column Reordering',
  examplePath: '../scripts/examples/example23-row-reordering.js',
  exampleSourceLink: 'https://github.com/adazzle/react-data-grid/blob/master/packages/react-data-grid/scripts/examples/example23-row-reordering.js'
});

关键修复点说明:

  1. 列配置添加id属性:每个列都设置了和key一致的唯一id,直接解决了id未定义的报错。
  2. 调整组件嵌套顺序:用列重排容器包裹行拖拽容器,确保列拖拽的事件能正常冒泡并触发onHeaderDrop。
  3. 完善onHeaderDrop逻辑:手动处理列数组的顺序调整,更新state中的列配置,完成列重排后的UI更新。
  4. 保留行拖拽原有逻辑:继续使用Selectors.moveRow处理行顺序调整,保证行拖拽功能正常。

这样修改后,你就能同时正常使用行拖拽和列重排功能,不会再出现之前的报错和事件不触发问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:12:17