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

react-chartjs-2中category scale注册失败与Canvas复用报错求助

解决 react-chartjs-2 + Chart.js 中的两个常见错误

一、"category" is not a registered scale 错误

你已手动注册CategoryScale但仍报错,可从以下几个方向排查解决:

1. 调整注册时机,全局单次注册

将Chart.register代码移至React应用的入口文件(如index.js或App.js),而非单个组件文件内。若在组件中注册,多次渲染时可能引发注册异常或实例共享问题。

示例(入口文件):

import { BarElement, CategoryScale, Chart, Legend, LinearScale, Title, Tooltip } from "chart.js";

// 全局注册所需组件,仅执行一次
Chart.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);

2. 显式指定坐标轴类型

在options中明确配置x轴类型为category,避免Chart.js自动推断出错:

const options = {
  responsive: true,
  scales: {
    x: {
      type: 'category', // 显式声明x轴类型
    },
  },
  plugins: {
    legend: { position: 'top' },
    title: { display: true, text: 'A title' },
  },
};

3. 校验依赖版本兼容性

确认react-chartjs-2@5.2.0与chart.js@4.3.0无版本冲突,可删除依赖文件后重新安装:

rm -rf node_modules package-lock.json
npm install

二、Canvas is already in use. Chart with ID '0' must be destroyed before the canvas with ID '' can be reused. 错误

该错误源于组件重渲染时旧Chart实例未被正确销毁,导致canvas被重复绑定,可通过以下方式解决:

1. 给Bar组件添加唯一key

当data或options频繁变化时,为<Bar>组件添加唯一key,强制React重建组件实例,避免复用旧canvas:

return <Bar key={JSON.stringify(data)} options={options} data={data}/>;

(若数据量较大,JSON.stringify性能不足,可改用递增计数器等状态变量作为key)

2. 用useRef手动管理Chart实例

通过useRef保存Chart实例,在组件卸载或数据更新前手动销毁旧实例:

import React, { useEffect, useRef } from "react"
import { Bar } from "react-chartjs-2"
import { BarElement, CategoryScale, Chart, Legend, LinearScale, Title, Tooltip } from "chart.js"

Chart.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend)

export default function Test() {
    const chartRef = useRef(null);
    const options = { /* 你的配置 */ };
    const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
    const data = { /* 你的数据 */ };

    useEffect(() => {
        // 组件卸载时销毁Chart实例
        return () => {
            if (chartRef.current) {
                chartRef.current.destroy();
            }
        };
    }, []);

    return <Bar ref={chartRef} options={options} data={data}/>;
}

3. 减少不必要的重渲染

检查父组件是否频繁触发Test组件重渲染,比如传递的props是否每次都生成新引用(如对象、数组)。可使用useMemo缓存options和data:

const options = useMemo(() => ({
    responsive: true,
    scales: { x: { type: 'category' } },
    plugins: {
        legend: { position: 'top' },
        title: { display: true, text: 'A title' },
    },
}), []);

const data = useMemo(() => ({
    labels,
    datasets: [
        {
            label: 'Dataset 1',
            data: labels.map(() => Math.random()),
            backgroundColor: 'rgba(255, 99, 132, 0.5)',
        },
        {
            label: 'Dataset 2',
            data: labels.map(() => Math.random()),
            backgroundColor: 'rgba(53, 162, 235, 0.5)',
        },
    ],
}), [labels]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 07:37:12