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

