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

Next.js环境下修复Flexmonster组件this.TD[this.j5] is null错误

问题:Next.js集成react-flexmonster出现this.TD[this.j5] is null错误

本地用Next.js框架引入react-flexmonster组件,修改组件后触发this.TD[this.j5] is null错误。已知Flexmonster基于客户端渲染(CSR),已经用自定义防抖hook延迟执行相关函数,错误截图如下:

错误截图

组件代码

import { useRef } from 'react';
import dynamic from 'next/dynamic';
import useDebounce from '@hooks/useDebounce';
import 'flexmonster/flexmonster.css';

const DynamicFlexMonster = dynamic(() => import('react-flexmonster'), {
  ssr: false,
});

const Flexmonster = ({
  dataSource = [],
  rows = [],
  columns = [],
  measures = [],
  formats = {},
  viewType,
  gridType,
  chartType,
}) => {
  const flexmonsterDataStructure = {
    dataSource: {
      data: dataSource,
    },
    slice: {
      rows,
      columns,
      measures,
    },
    options: {
      viewType,
      grid: {
        type: gridType,
        showHeader: false,
        showTotals: false,
        showGrandTotals: 'off',
      },
      chart: {
        type: chartType,
      },
      showEmptyData: true,
    },
    formats,
  };

  const ref = useRef(null);
  const [debounceReport, setDebounceReport] = useDebounce(null);

  const onReportComplete = () => {
    setDebounceReport(ref.current, 1000);

    if (debounceReport) {
      console.log('>>>>', ref.current.flexmonster.getReport());
    }
  };

  return (
    <>
      <DynamicFlexMonster
        ref={ref}
        toolbar={false}
        width="100%"
        report={flexmonsterDataStructure}
        reportcomplete={onReportComplete}
      />
    </>
  );
};

export default Flexmonster;

解决思路

1. 修正防抖逻辑的使用方式

当前防抖实现存在逻辑问题:setDebounceReport是异步更新状态,导致onReportComplete里的if (debounceReport)永远不会触发,反而可能引发实例引用异常。直接把获取报表的逻辑封装到防抖回调里:

// 调整useDebounce的使用,传入回调函数
const debounceGetReport = useDebounce((instance) => {
  if (instance?.flexmonster) {
    console.log('>>>>', instance.flexmonster.getReport());
  }
}, 1000);

const onReportComplete = () => {
  debounceGetReport(ref.current);
};

2. 缓存Report结构避免频繁重渲染

每次组件渲染都会新建flexmonsterDataStructure对象,导致Flexmonster频繁初始化,容易触发内部状态错误。用useMemo缓存这个对象,只有依赖项变化时才重建:

import { useRef, useMemo } from 'react'; // 新增useMemo导入

// 缓存report对象
const flexmonsterDataStructure = useMemo(() => ({
  dataSource: {
    data: dataSource,
  },
  slice: {
    rows,
    columns,
    measures,
  },
  options: {
    viewType,
    grid: {
      type: gridType,
      showHeader: false,
      showTotals: false,
      showGrandTotals: 'off',
    },
    chart: {
      type: chartType,
    },
    showEmptyData: true,
  },
  formats,
}), [dataSource, rows, columns, measures, formats, viewType, gridType, chartType]);

3. 确保实例完全就绪后再操作

reportcomplete事件触发时,Flexmonster内部可能还没完全初始化完成,可以改用ready事件,或者在防抖里增加实例有效性检查:

// 改用ready事件
const onReady = () => {
  debounceGetReport(ref.current);
};

// 组件中替换reportcomplete为ready
<DynamicFlexMonster
  ref={ref}
  toolbar={false}
  width="100%"
  report={flexmonsterDataStructure}
  ready={onReady}
/>

4. 校验数据源格式

确认dataSource的格式符合Flexmonster要求,比如字段类型统一、没有嵌套异常数据,非法数据可能导致内部渲染逻辑抛出错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:24:25