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

React中更新Mermaid甘特图Props时触发渲染语法错误求助

React中Mermaid甘特图Props更新时渲染异常问题

问题场景

首次加载和页面刷新时,Mermaid甘特图可正常显示;但修改props触发componentDidUpdate()执行指定代码后,会出现错误,必须刷新页面才能恢复。触发错误的代码片段:

if (prevProps.chart !== this.props.chart) {
    //console.log("the state has changed comp", this.state.chart)
    document
        .getElementById("mermaid-chart")
        .removeAttribute("data-processed");
    mermaid.contentLoaded()
}

完整组件代码:

import React from "react";
import mermaid from "mermaid";


mermaid.initialize({
    startOnLoad: true,
    securityLevel: "loose",
    gantt: {
        barHeight: 40,
        barGap: 15,
        sectionFontSize: 20,
        leftPadding: 200,
        numberSectionStyles: 2,
        fontSize: 15,
    }
});


export default class Mermaid extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            chart: props.chart,
        };
    }

    componentDidMount() {
        //console.log("comp mounted")
        mermaid.contentLoaded();
    }

    componentDidUpdate(prevProps, prevState) {
         //console.log("the state has not changed comp", prevProps.chart);
        // console.log("the current state has not changed comp", this.props.chart);
        if (prevProps.chart !== this.props.chart) {
            //console.log("the state has changed comp", this.state.chart)
            document
                .getElementById("mermaid-chart")
                .removeAttribute("data-processed");
            mermaid.contentLoaded()
            
        }
    }
    render() {
        return <div className="mermaid" id="mermaid-chart">{this.state.chart}</div>;
    }
}

组件调用方式:

return (<Mermaid chart={chart} />)

使用旧版本Mermaid.js时,会提示试图用文本<svg id =....渲染图表,推测更新时Mermaid未读取新的props内容,反而渲染了div中已生成的SVG元素。


解决办法

问题根源

  1. 构造函数中把props.chart存入state,但props更新时未同步state,导致render始终使用旧的图表文本
  2. 调用全局的mermaid.contentLoaded()时,div内容未及时更新为新props值,旧SVG未被清除,导致解析错误

修复代码

import React from "react";
import mermaid from "mermaid";


mermaid.initialize({
    startOnLoad: true,
    securityLevel: "loose",
    gantt: {
        barHeight: 40,
        barGap: 15,
        sectionFontSize: 20,
        leftPadding: 200,
        numberSectionStyles: 2,
        fontSize: 15,
    }
});


export default class Mermaid extends React.Component {
    constructor(props) {
        super(props);
        this.chartRef = React.createRef();
    }

    componentDidMount() {
        this.renderMermaid();
    }

    componentDidUpdate(prevProps) {
        if (prevProps.chart !== this.props.chart) {
            this.renderMermaid();
        }
    }

    renderMermaid = () => {
        const container = this.chartRef.current;
        if (!container) return;
        
        // 清空容器并写入新的图表文本
        container.innerHTML = this.props.chart;
        container.removeAttribute("data-processed");
        
        // 单独渲染当前元素,避免全局渲染的冲突
        mermaid.render(
            "mermaid-chart",
            this.props.chart,
            (svgCode) => {
                container.innerHTML = svgCode;
            }
        );
    }

    render() {
        return <div className="mermaid" ref={this.chartRef}></div>;
    }
}

关键优化点

  • 移除冗余state,直接使用this.props.chart确保内容实时同步
  • 用React ref替代getElementById,避免DOM操作的潜在冲突
  • 使用mermaid.render()单独处理当前元素,替代全局的contentLoaded(),精准控制渲染流程,避免解析旧SVG内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:22:46