CoreUI ChartBar组件报Canvas is already in use错误如何解决
问题产生原因
这个报错是Chart.js的内置校验逻辑触发:同一个canvas DOM元素同一时间只能绑定一个Chart实例,新建实例前必须先销毁已经存在的旧实例,结合调用栈中出现的commitDoubleInvokeEffectsInDEV标记,核心触发原因有两个:
- React 18 开发环境默认开启严格模式(StrictMode),会对组件的useEffect挂载逻辑做双调用校验,而你使用的
@coreui/react-chartjs版本存在逻辑缺陷:useEffect执行时创建了Chart实例,但没有在effect清理函数中调用chart.destroy()销毁实例,第二次effect执行时就会在同一个canvas上重复创建实例,直接触发报错。这个报错通常仅在本地开发环境出现,生产环境构建不会触发effect双调用逻辑。 - 你当前的写法直接在JSX属性中传入内联对象,每次组件重渲染时
data属性都会生成新的对象引用,会触发CChart组件的重渲染逻辑,如果重渲染时旧实例未被正确销毁,也会触发同样的canvas占用错误。
可行修复方案
按优先级从高到低选择:
- 优先升级依赖:将
@coreui/react-chartjs升级到最新稳定版,新版本已经修复了effect清理逻辑缺失的问题,组件重渲染、卸载前都会主动销毁旧Chart实例,从根源解决canvas复用冲突。 - 固定配置引用:不要在JSX中直接写内联的data、options配置,将配置抽到组件作用域外,或者用
useMemo缓存配置对象,避免无意义的重渲染触发图表重复初始化,示例写法:
// 组件外定义,或组件内用useMemo包裹做缓存 const chartData = { labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], datasets: [ { label: 'GitHub Commits', data: [40, 20, 12, 39, 10, 40, 39, 80, 40], }, ] } // JSX中直接引用缓存后的配置 <CChartBar data={chartData} type="bar" />
- 临时兼容方案:如果暂时无法升级依赖,可以给CChartBar组件添加唯一的
key属性,强制组件在更新时走完整的卸载-重挂载流程,避免复用同一个canvas实例初始化,示例:
<CChartBar key="github-commit-bar-chart" data={chartData} type="bar" />
- 不推荐的临时方案:移除根组件的
<StrictMode>包裹,关闭React 18开发环境的双调用校验,但会丢失严格模式的问题提前检测能力,只建议临时调试使用。
额外提示:你当前传入的配置中labels数组长度为7,但对应数据集的data数组长度为9,会导致图表渲染时x轴刻度与数据点无法一一对应,修复canvas报错后建议调整两个数组长度保持一致。
内容的提问来源于stack exchange,提问作者thushanthan amalanathan
相关产品推荐
相关产品推荐

