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

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属于曲线路径的控制点),可通过以下步骤解决:

  1. 动态导入Line组件并禁用SSR
    修改组件导入方式,使用Next.js的dynamic导入确保组件仅在客户端渲染:

    import dynamic from 'next/dynamic';
    
    const Line = dynamic(() => import('react-chartjs-2').then(mod => mod.Line), {
      ssr: false,
    });
    
  2. 手动注册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的填充效果
    );
    
  3. 调试曲线参数(可选)
    临时将tension设为0(禁用曲线)或fill设为false,验证是否为曲线渲染逻辑导致的问题,再逐步恢复设置调试。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:59:57