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

React中使用Chart.js报错:无法读取undefined的datasets属性

解决Chart.js实例data为undefined及更新报错问题

看起来你遇到的核心问题是Chart实例初始化后data属性丢失,导致更新时无法访问datasets。我来帮你一步步排查和解决:

1. 先排查DOM元素获取的可靠性

你用document.getElementById获取canvas元素,虽然componentDidMount是组件挂载后执行,但在React里推荐用React Refs来获取DOM元素,这样更可靠,避免因React的DOM更新机制导致元素获取异常:

// 组件构造函数中创建ref
constructor(props) {
  super(props);
  this.chartRef = React.createRef();
  this.usageChart = null;
}

// render方法里给canvas绑定ref
render() {
  return (
    // ...你的其他组件内容
    <canvas ref={this.chartRef} id="proc_usage"></canvas>
    // ...
  );
}

// componentDidMount中通过ref获取上下文
componentDidMount() {
  // 确保ref已关联到DOM元素
  if (!this.chartRef.current) return;
  
  const chartContext = this.chartRef.current.getContext('2d');
  const initialDataIdle = [100, 100, 100, 100, 100, 100, 100, 100, 100, 100];
  const initialDataOther = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  
  console.log("Creating chart");
  this.usageChart = new Chart(chartContext, {
    type: "line",
    data: {
      datasets: [
        { label: "User", fill: true, data: initialDataOther, backgroundColor: "rgba(244, 143, 177, 0.8)" },
        { label: "System", fill: true, data: initialDataOther, backgroundColor: "rgba(255, 235, 59, 0.8)" },
        { label: "IRQ", fill: true, data: initialDataOther, backgroundColor: "rgba(100, 181, 246, 0.8)" },
        { label: "Idle", fill: true, data: initialDataIdle, backgroundColor: "rgba(150, 150, 150, 0.4)" }
      ]
    },
    options: {
      // 注意这里的scales配置要对应你的Chart.js版本!
      scales: {
        // 如果是Chart.js v3+,写法是x/y而不是xAxes/yAxes
        x: { stacked: true },
        y: { stacked: true }
      },
      plugins: { stacked100: { enable: true } }
    }
  });
  
  // 打印完整实例,而不是只打印data,看看实例结构是否正常
  console.log("Chart instance:", this.usageChart);
  console.log("Chart data:", this.usageChart?.data); // 用可选链避免直接访问undefined报错
}

2. 检查Chart.js和stacked100插件的版本兼容性

这是最容易踩坑的点:

  • 如果你用的是Chart.js v3+,必须安装chartjs-plugin-stacked100@v2.x以上版本
  • 如果你用的是Chart.js v2,则需要安装chartjs-plugin-stacked100@v1.x

可以查看你的package.json确认版本,或者重新安装兼容的版本:

# 安装Chart.js v3 + 兼容的插件版本
npm install chart.js@^3.9.1 chartjs-plugin-stacked100@^2.0.3

另外,Chart.js v3和v2的配置项差异很大,比如你原来的xAxes/yAxes写法是v2的,v3里要改成x/y,如果配置不匹配,Chart实例可能会初始化失败,导致data属性丢失。

3. 给更新逻辑加安全校验

在componentDidUpdate里,先判断Chart实例是否存在,避免因实例未初始化导致报错:

componentDidUpdate(prevProps, prevState) {
  // 先确认实例已创建
  if (!this.usageChart) {
    console.warn("Chart instance not initialized yet");
    return;
  }
  
  usages['User'] = userUsage;
  usages['System'] = sysUsage;
  usages['IRQ'] = irqUsage;
  usages['Idle'] = idleUsage;
  
  console.log("updating chart");
  this.usageChart.data.datasets.forEach((dataset) => {
    dataset.data.shift();
    dataset.data.push(usages[dataset.label]);
  });
  
  this.usageChart.update();
  console.log("chart updated");
}

4. 组件卸载时销毁Chart实例(可选但推荐)

避免内存泄漏,在组件卸载时销毁Chart实例:

componentWillUnmount() {
  if (this.usageChart) {
    this.usageChart.destroy();
    this.usageChart = null;
  }
}

排查步骤总结

  1. 先用Refs替换document.getElementById获取canvas,确保DOM元素获取可靠
  2. 确认Chart.js和插件版本兼容,配置项符合当前版本要求
  3. 打印完整的Chart实例,查看是否初始化成功
  4. 在更新逻辑前加实例存在校验

按这个流程排查,应该能解决data为undefined的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:21:26