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

React函数组件使用Chart.js无法切换数据报properties undefined错误如何解决

React中Chart.js实例跨作用域访问、更新的解决方案

问题根因

报错核心原因是对React useState的使用错误,附带存在useEffect、逻辑判断的写法问题:

  • 直接给setPositiveChart赋值,覆盖了useState返回的状态更新函数,Chart实例从未被存入positiveChart状态,导致状态始终是初始值undefined,访问属性时自然报错
  • 直接给useEffect传入async回调,返回的Promise会覆盖清理函数,导致Chart实例销毁逻辑不生效
  • toggle函数的两个并列if判断存在逻辑冲突,执行hide后第二个判断条件会立刻成立,导致刚隐藏的数据集又被显示

修正方案

按照以下步骤修改即可实现全组件内访问Chart实例、正常触发更新:

  1. 在makeChart函数中先创建Chart实例,再调用state更新函数将实例存入状态
  2. 修正useEffect的异步写法和销毁逻辑
  3. 优化toggle函数的判断逻辑
    修正后的完整代码如下:
import React, { useContext, useEffect, useState } from "react";
import "./questions_trends.css";
import axios from 'axios';
import ReactTooltip from 'react-tooltip';
import { Chart } from "chart.js";
// 注意如果你的UserContext没有在当前文件导入,需要补充对应导入逻辑
const UserContext = React.createContext();

function Trends(){
    const user_context = useContext(UserContext)
    const [positiveChart, setPositiveChart] = useState(undefined);

    function makeChart(data){
        // 先创建Chart实例
        const chartInstance = new Chart('positiveChart', {
            type: 'bar',
            data: { 
                labels: data.positive,
                datasets: [
                {
                    label: 'Team Positive',
                    data: data.team_positive,
                    backgroundColor: data.color
                },
                {
                    label: 'You Positive',
                    data: data.positive,
                    backgroundColor: data.color
                }]
            },
            options: {}
        });
        // 调用state更新函数将实例存入状态
        setPositiveChart(chartInstance);
    }

    function toggle(value) {
        // 先判断实例是否存在,避免报错
        if(!positiveChart) return;
        // 改用if else避免逻辑冲突
        if(positiveChart.isDatasetVisible(value)){
            positiveChart.hide(value)
        } else {
            positiveChart.show(value)
        }
    }

    useEffect(() => {
        // 异步逻辑写在useEffect内部的独立函数中,不要直接给useEffect回调加async
        const fetchData = async () => {
            let result = await axios.get("/api/monthly_tones")
            makeChart(result.data)
        }
        fetchData();

        // 清理逻辑写在当前useEffect的返回中,不需要单独写一个useEffect
        return () => {
            if(positiveChart) {
                positiveChart.destroy()
            }
        }
    }, []);

    return (                    
        <div className="question_positivity_container">
            <canvas id="positiveChart" width="auto" height="70vh"></canvas>
            <button onClick={() => toggle(0)}>See All Cratic</button>
        </div>
    );
};

export default Trends;

验证逻辑

修改完成后:

  • Chart初始化完成后实例会被存入positiveChart状态,全组件范围内都可以正常访问
  • 点击按钮可正常切换数据集的显隐
  • 组件卸载时会自动销毁Chart实例,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:06:04