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

ReactJS中Tabulator表格获取选中数据报错求助

解决React中Tabulator调用getSelectedData时table为undefined的问题

问题核心原因

  1. 用普通let table存储表格实例,组件重渲染时会被重置为undefined
  2. DOM引用赋值方式错误,未正确使用useRef的current属性
  3. useEffect依赖数组不合理,导致表格实例被重复初始化丢失
  4. 主表格未开启selectable配置,无法选中行

修复后的完整代码

import { useState, useEffect, useRef } from 'react';
import Button from '你的Button组件路径';
import Tabulator from 'tabulator-tables';
import 'tabulator-tables/dist/css/tabulator.min.css';

const SkusTable = ({ data }) => {
  const [selectedData, setSelectedData] = useState([]);

  // 用useRef持久化表格实例,避免重渲染丢失
  const tableRef = useRef(null);
  const mainTable = useRef(null);
  const subTables = useRef([]); // 存储子表格实例,方便获取选中数据

  const tabulatorOptions = {
    reactiveData: true,
    data,
    layout: "fitData",
    dataTreeStartExpanded: true,
    progressiveLoad: "scroll",
    paginationSize: 20,
    selectable: true, // 主表格开启行选中
    columns: SkusTableColumns,
    dataTreeChildField: "_children",
    rowFormatter: (row) => {
      const holderEl = document.createElement("div");
      const tableEl = document.createElement("div");

      holderEl.style.padding = "10px 30px 10px 10px";
      holderEl.appendChild(tableEl);
      row.getElement().appendChild(holderEl);

      if (row.getData()._children?.length > 0) {
        const subTable = new Tabulator(tableEl, {
          layout: "fitColumns",
          dataTreeChildField: "_children",
          selectable: true,
          data: row.getData()._children,
          columns: SubColumns
        });
        subTables.current.push(subTable);
      }
    }
  };

  const initTable = (el, options) => {
    if (!el) return null;
    return new Tabulator(el, options);
  };

  useEffect(() => {
    // 初始化主表格
    mainTable.current = initTable(tableRef.current, tabulatorOptions);

    // 组件卸载时销毁表格,避免内存泄漏
    return () => {
      mainTable.current?.destroy();
      subTables.current.forEach(table => table.destroy());
      subTables.current = [];
    };
  }, [data]); // 仅当数据源变化时重建表格

  const clickHandler = () => {
    let allSelected = [];
    // 获取主表格选中数据
    if (mainTable.current) {
      allSelected = [...allSelected, ...mainTable.current.getSelectedData()];
    }
    // 获取所有子表格选中数据
    subTables.current.forEach(table => {
      allSelected = [...allSelected, ...table.getSelectedData()];
    });
    setSelectedData(allSelected);
  };

  useEffect(() => {
    console.log({ selectedData, table: mainTable.current });
  }, [selectedData]);

  return (
    <>
      <Button className="ms-2 mb-2" color="primary" onClick={clickHandler}>
        Get Data
      </Button>
      <h2>Number: {selectedData.length}</h2>
      <div ref={tableRef} />
    </>
  );
};

export default SkusTable;

关键修改点说明

  • 用useRef存储实例:useRef的current属性会在组件生命周期内保持引用,不会随重渲染重置,解决table为undefined的核心问题
  • 正确设置DOM引用:直接将tableRef传给div的ref属性,React会自动把DOM元素赋值给tableRef.current
  • 优化useEffect依赖:仅在data变化时初始化表格,避免因selectedData更新导致表格实例被重复创建
  • 添加清理逻辑:在组件卸载时销毁所有表格实例,防止内存泄漏
  • 合并主/子表格选中数据:如果需要同时获取子表格的选中行,通过subTables数组收集所有子表格实例,统一获取数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:55:26