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

NextJS集成ChartJS报错:TypeError: Cannot read properties of null (reading 'useRef')

解决NextJS中使用ChartJS出现的useRef错误

错误原因

  • NextJS默认启用服务端渲染(SSR),但react-chartjs-2内部依赖浏览器DOM环境,且使用了useRef这类客户端专属API,服务端渲染阶段无法获取DOM相关对象,因此抛出Cannot read properties of null (reading 'useRef')错误。
  • 代码存在语法问题:<canvas>是替换型元素,内部不能嵌套<h2>和<Line>组件,会导致渲染异常。

解决方案

方案1:动态导入组件并禁用SSR

在页面中通过NextJS的dynamic函数导入图表组件,强制组件仅在客户端渲染:

修改root/pages/admin/home.js:

import Head from 'next/head'
import Image from 'next/image'
import dynamic from 'next/dynamic'

// 动态导入组件,禁用SSR
const LineGraph = dynamic(() => import('../../components/admin/line'), {
  ssr: false,
  loading: () => <p>加载图表中...</p>
})

export default function Home() {
    return (
        <div className="container">
            <Head>
                <title>Create Next App</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <main>
                <LineGraph />
            </main>

        </div>
    )
}

同时修复root/components/admin/line.js中的canvas嵌套问题:

import React from 'react';
import { Line } from 'react-chartjs-2';
import Chart from 'chart.js/auto';

const data = {
  labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
  datasets: [
    {
      label: 'My First dataset',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'rgba(75,192,192,0.4)',
      borderColor: 'rgba(75,192,192,1)',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'rgba(75,192,192,1)',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [65, 59, 80, 81, 56, 55, 40]
    }
  ]
};

const LineGraph = () => {
  return (
    <div>
      <h2>Line Example</h2>
      <Line
        id="lineChart"
        data={data}
        width={400}
        height={400}
      />
    </div>
  );
}

export default LineGraph;

方案2:直接使用Chart.js核心库绕开SSR限制

若不想依赖react-chartjs-2,可直接使用chart.js核心库,通过useEffect确保仅在客户端初始化图表:

修改root/components/admin/line.js:

import React, { useEffect, useRef, useState } from 'react';
import Chart from 'chart.js/auto';

const data = {
  labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
  datasets: [
    {
      label: 'My First dataset',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'rgba(75,192,192,0.4)',
      borderColor: 'rgba(75,192,192,1)',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'rgba(75,192,192,1)',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [65, 59, 80, 81, 56, 55, 40]
    }
  ]
};

const LineGraph = () => {
  const chartRef = useRef(null);
  const [chartInstance, setChartInstance] = useState(null);

  useEffect(() => {
    // 仅在客户端初始化图表
    if (chartRef.current && !chartInstance) {
      const ctx = chartRef.current.getContext('2d');
      const newChart = new Chart(ctx, {
        type: 'line',
        data: data
      });
      setChartInstance(newChart);
    }

    // 组件卸载时销毁图表,避免内存泄漏
    return () => {
      if (chartInstance) {
        chartInstance.destroy();
      }
    };
  }, [chartInstance]);

  return (
    <div>
      <h2>Line Example</h2>
      <canvas ref={chartRef} width={400} height={400} />
    </div>
  );
}

export default LineGraph;

额外注意事项

  • 确保已安装所需依赖:npm install chart.js react-chartjs-2(方案1需保留react-chartjs-2,方案2仅需chart.js)
  • 若使用NextJS 13+ App Router,需在图表组件顶部添加'use client'指令,标记为客户端组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:50:35