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

运行React项目时D3.js生成的SVG对象无法每次正常显示如何解决

React + D3 矩形偶现无法渲染问题修复方案

问题根因

代码核心问题是D3操作执行时机早于React SVG元素的挂载时机:
React函数组件会先执行函数体内部所有同步代码,再将return返回的JSX渲染为真实DOM插入页面。你在return之前执行d3.select("svg")时,页面上还没有对应的SVG节点,D3选中的是空集合,追加矩形的操作自然不会生效,偶尔成功是缓存了上一次渲染的旧DOM节点导致的巧合。
另外代码存在冗余逻辑:已经通过import * as d3 from "d3"引入了D3依赖,不需要再在JSX里插入D3的CDN script标签。

修复后代码

Graph.js

import * as d3 from "d3"
import { useEffect, useRef } from "react"

function Graph(props) {
    // 用useRef绑定当前组件的SVG节点,避免全局选择冲突
    const svgRef = useRef(null)

    useEffect(() => {
        // useEffect回调在DOM挂载完成后执行,保证SVG节点已存在
        const svg = d3.select(svgRef.current)
        // 清空已有内容,避免重渲染时重复叠加元素
        svg.selectAll("*").remove()
        
        svg.append('rect')
        .attr("height", 10)
        .attr("width", 10)
        .style("fill", "Green");
    }, []) // 空依赖数组保证仅在组件首次挂载完成后执行一次

    return (
        <div>
            <svg ref={svgRef} width="640" height="480"></svg>
        </div>
    )
}

export default Graph

App.js

无需修改,保持原有逻辑即可。

核心调整说明

  • 用useRef绑定SVG元素,直接获取当前组件内的SVG节点,比全局d3.select("svg")更稳定,不会和页面其他SVG元素冲突
  • 用useEffect将D3操作推迟到DOM挂载完成后执行,保证选中的节点一定存在
  • 增加清空SVG内容的逻辑,避免组件重渲染时重复追加相同元素
  • 移除冗余的D3 CDN和index.js引入,通过包管理引入的D3已经可以正常使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:36:04