Next.js生产构建中Chart.js报Cannot set properties of undefined(setting 'cp1x')错误
Chart.js v4.x + Next.js v15 生产环境折线图渲染报错:Cannot set properties of undefined (setting 'cp1x')
开发模式(npm run dev)下折线图渲染正常,但执行npm run build && npm start构建生产环境并运行后,控制台抛出以下错误:
Uncaught TypeError: Cannot set properties of undefined (setting 'cp1x') at eH (6693-33f3835dce261e0f.js:1:31394) at t8.updateControlPoints (ca377847-7eb0c2c58d1a2c2a.js:1:98634) at Object.beforeDraw (ca377847-7eb0c2c58d1a2c2a.js:1:109969) at $ (6693-33f3835dce261e0f.js:1:10221) at tS._notify (ca377847-7eb0c2c58d1a2c2a.js:1:72159) at tS.notify (ca377847-7eb0c2c58d1a2c2a.js:1:71951) at tG.notifyPlugins (ca377847-7eb0c2c58d1a2c2a.js:1:90935) at tG.draw (ca377847-7eb0c2c58d1a2c2a.js:1:86179) at ca377847-7eb0c2c58d1a2c2a.js:1:906 at Map.forEach (<anonymous>) at a._update (ca377847-7eb0c2c58d1a2c2a.js:1:688) at ca377847-7eb0c2c58d1a2c2a.js:1:582

代码片段
export default function LineChart({ labels, incomeData, expenseData }) { const cleanIncome = incomeData.map(val => (typeof val === "number" ? val : 0)); const cleanExpense = expenseData.map(val => (typeof val === "number" ? val : 0)); const data = { labels: labels, datasets: [ { label: 'Income', data: cleanIncome, fill: true, backgroundColor: 'rgba(34, 197, 94, 0.2)', // 绿色填充 borderColor: 'rgba(34, 197, 94, 1)', tension: 0.3, }, { label: 'Expense', data: cleanExpense, fill: true, backgroundColor: 'rgba(239, 68, 68, 0.2)', // 红色填充 borderColor: 'rgba(239, 68, 68, 1)', tension: 0.3, }, ], }; const options = { responsive: true, maintainAspectRatio: false, plugins: { legend: { labels: { color: "#fff" }, } }, scales: { x: { ticks: { color: "#fff" }, grid: { color: "rgba(255, 255, 255, 0.2)", drawBorder: true, }, }, y: { ticks: { color: "#fff" }, grid: { color: "rgba(255, 255, 255, 0.2)", drawBorder: true, }, }, }, }; return ( <div className="h-[70vh] sm:h-[80vh] p-6 rounded-lg shadow-lg"> <Line data={data} options={options} /> </div> ); }
控制台输出数据
cleanIncome - [2000,3300,876,0,1221,0,243,23,0,234,123,1] cleanExpense - [200,0,0,199,0,245,0,0,2312,0,0,12] labels - ["01 Apr","02 Apr","03 Apr","04 Apr","09 Apr","13 Apr","15 Apr","16 Apr","17 Apr","18 Apr","19 Apr","20 Apr"]
(所有数组长度均为12)
已执行的排查操作
- 验证labels、incomeData、expenseData数组长度对齐,且无null/undefined值
- 更新Chart.js至最新版本,问题仍存在
解决方案
该错误是Next.js生产环境SSR/SSG机制与Chart.js的DOM依赖冲突导致的——Chart.js在服务端渲染时无法正确初始化贝塞尔曲线控制点(cp1x属于曲线路径的控制点),可通过以下步骤解决:
动态导入Line组件并禁用SSR
修改组件导入方式,使用Next.js的dynamic导入确保组件仅在客户端渲染:import dynamic from 'next/dynamic'; const Line = dynamic(() => import('react-chartjs-2').then(mod => mod.Line), { ssr: false, });手动注册Chart.js必要模块
Chart.js v4.x需要手动注册核心模块,在组件中添加:import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler } from 'chart.js'; ChartJS.register( CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler // 用于支持fill:true的填充效果 );调试曲线参数(可选)
临时将tension设为0(禁用曲线)或fill设为false,验证是否为曲线渲染逻辑导致的问题,再逐步恢复设置调试。
内容的提问来源于stack exchange,提问作者Utkarsh Tiwari
相关产品推荐
相关产品推荐

