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

React16中使用Chart.js 3.9.1注册Sankey组件时出现prototype未定义错误

问题:React 16 + Chart.js v3.9.1 桑基图注册报错 Uncaught TypeError: Cannot read properties of undefined (reading 'prototype')

问题背景

React 16项目中使用Chart.js v3.9.1实现桑基图可视化,因无法升级Webpack 5或调整Babel配置选择该版本。执行ChartJS.register(SankeyController, Flow)时触发错误:Uncaught TypeError: Cannot read properties of undefined (reading 'prototype')。已尝试父组件懒加载,问题未解决;但相同代码在测试项目中可正常运行。

组件代码

import { Chart as ChartJS, registerables } from "chart.js";
import { SankeyController, Flow } from "chartjs-chart-sankey";
import React, { useState} from "react";
import "./SankeyChart.css";
import { Chart } from "react-chartjs-2";

interface SankeyChartProps {
  config: any;
}

ChartJS.register(SankeyController, Flow);

export const SankeyChart = (props:SankeyChartProps) => {

  const [colors,setColors] = useState({
    Oil: "#000000",
    Coal: "gray",
    "Fossil Fuels": "slategray",
    Electricity: "blue",
    Energy: "orange",
  })
  const [priority, setPriority] = useState({
    Oil: 1,
    "Natural Gas": 2,
    Coal: 3,
    "Fossil Fuels": 1,
    Electricity: 2,
    Energy: 1,
  })
  const [labels, setLabels] = useState({
    Oil: "black gold (label changed)",
  })
  const [data, setData] = useState({
    datasets: [
      {
        data: [
          { from: "Oil", to: "Fossil Fuels", flow: 15 },
          { from: "Natural Gas", to: "Fossil Fuels", flow: 20 },
          { from: "Coal", to: "Fossil Fuels", flow: 25 },
          { from: "Coal", to: "Electricity", flow: 25 },
          { from: "Fossil Fuels", to: "Energy", flow: 60 },
          { from: "Electricity", to: "Energy", flow: 25 },
        ],
        priority,
        labels,
        colorFrom: (c) => getColor(c.dataset.data[c.dataIndex].from),
        colorTo: (c) => getColor(c.dataset.data[c.dataIndex].to),
        borderWidth: 2,
        borderColor: "black",
      },
    ],})
  const [options, setOptions] = useState({
    plugins: {
      tooltip: {
        callbacks: {
          label: function (context) {
            const { from, to, flow } = context.raw;
            return `${from} → ${to}: ${flow}`;
          },
        },
      },
    },
  })
  
  
  function getColor(name)
  {
    return colors[name] || "green"
  }
  return <Chart type="sankey" data={data} options={options}/>;
};

解决方案

1. 锁定依赖版本兼容性

确保chartjs-chart-sankey版本与Chart.js v3.9.1完全适配,在package.json中明确指定:

"chart.js": "3.9.1",
"chartjs-chart-sankey": "^3.0.0"

执行npm install重新安装依赖,避免版本不匹配导致的原型链错误。

2. 调整注册时机到组件挂载阶段

将注册逻辑移至useEffect中,避免模块加载时的执行顺序问题,同时防止重复注册:

import { Chart as ChartJS, registerables } from "chart.js";
import { SankeyController, Flow } from "chartjs-chart-sankey";
import React, { useState, useEffect} from "react";
import "./SankeyChart.css";
import { Chart } from "react-chartjs-2";

interface SankeyChartProps {
  config: any;
}

export const SankeyChart = (props:SankeyChartProps) => {
  useEffect(() => {
    // 检查桑基图控制器是否已注册,避免重复执行
    if (!ChartJS.getController('sankey')) {
      ChartJS.register(SankeyController, Flow);
    }
  }, []);

  // 其余组件代码保持不变
};

3. 排查项目内重复注册冲突

检查项目其他文件是否存在Chart.js组件注册代码,重复注册可能导致原型链异常。确保全局仅注册一次桑基图相关控制器。

4. 切换导入方式适配旧模块系统

若项目使用CommonJS模块解析存在问题,尝试改用require导入:

const ChartJS = require('chart.js');
const { SankeyController, Flow } = require('chartjs-chart-sankey');
const React = require('react');
const { useState, useEffect } = React;
const { Chart } = require('react-chartjs-2');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:53:15