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

React中Sunburst-chart组件重渲染时图表重复生成的解决方法

解决React中sunburst-chart数据更新时重复生成图表的问题

你遇到的问题根源在于:每次useEffect因data更新触发时,都重新调用Sunburst()创建了全新的图表实例,旧实例未被清理,导致新图表直接叠加在旧图表之上,而非更新现有图表。

核心解决方案

  1. 复用图表实例:通过useRef保存已创建的Sunburst实例,避免数据更新时重复初始化。
  2. 用React Refs获取容器:替代document.getElementById,更符合React组件化规范,同时避免全局ID冲突。
  3. 按需清理(可选):组件卸载时清空容器内容,防止内存泄漏。

修改后的完整代码

import React, { useEffect, useRef } from 'react'
import Sunburst from 'sunburst-chart'
import * as d3 from 'd3'

const SunburstChart = ({ data }) => {
  const color = d3.scaleOrdinal(d3.schemePaired)
  // 存储图表实例的ref
  const chartInstanceRef = useRef(null)
  // 存储图表容器的ref
  const containerRef = useRef(null)

  useEffect(() => {
    if (!containerRef.current) return

    if (!chartInstanceRef.current) {
      // 首次渲染:创建图表实例并挂载到容器
      chartInstanceRef.current = Sunburst()
        .width(740)
        .height(740)
        .sort((a, b) => b.value - a.value)
        .color((d) => color(d.name))
        .excludeRoot(true)(containerRef.current)
    }

    // 数据更新:复用已有实例,仅更新数据
    chartInstanceRef.current.data(data)

    // 组件卸载时清理
    return () => {
      if (containerRef.current) {
        containerRef.current.innerHTML = ''
      }
      chartInstanceRef.current = null
    }
  }, [data])

  return (
    <div id="chart-container">
      <div ref={containerRef}></div>
    </div>
  )
}

export default SunburstChart

关键说明

  • chartInstanceRef:保存第一次创建的Sunburst实例,后续数据更新时直接调用data(data)方法即可触发图表更新,无需重新初始化。
  • containerRef:通过React原生ref获取DOM容器,比全局ID选择器更可靠,尤其适合组件复用场景。
  • 清理函数:组件卸载时清空容器内容并重置实例引用,避免残留的DOM节点和内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:45:41