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元素。
解决办法
问题根源
- 构造函数中把
props.chart存入state,但props更新时未同步state,导致render始终使用旧的图表文本 - 调用全局的
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
相关产品推荐
相关产品推荐

