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

ReactJS中如何移除Mermaid默认错误SVG并替换为上一次正常渲染SVG

React中Mermaid解析错误时替换为上一次正确渲染的SVG

当Mermaid代码解析出错时,默认会生成错误提示SVG,要实现隐藏错误SVG并展示上一次正确图表的效果,可以通过优化状态管理和渲染逻辑来实现。以下是调整后的完整实现:

import { useState, useEffect, useRef } from 'react';

// 初始化Mermaid,关闭自动加载,手动控制渲染时机
mermaid.initialize({
    startOnLoad: false
});

const Mermaid = React.forwardRef((props, ref) => {
    const { code, handleMessage, handleExit } = props;
    
    // 简化状态:只维护关键数据
    const [lastValidCode, setLastValidCode] = useState('');
    const [hasError, setHasError] = useState(false);
    const [errorMessage, setErrorMessage] = useState('');
    
    const chartContainerRef = useRef(null);

    useEffect(() => {
        if (!chartContainerRef.current) return;
        
        // 清空容器,准备渲染
        chartContainerRef.current.innerHTML = '';
        
        let isCurrentCodeValid = true;

        // 覆盖Mermaid的解析错误回调
        const originalParseError = mermaid.parseError;
        mermaid.parseError = (err) => {
            isCurrentCodeValid = false;
            setHasError(true);
            setErrorMessage(err?.message || '语法解析错误');
            // 调用传入的错误处理回调
            handleMessage?.(err?.message);
        };

        // 尝试渲染当前代码
        const renderChart = async () => {
            try {
                // 手动调用Mermaid渲染
                const { svg } = await mermaid.render('mermaid-chart', code);
                if (isCurrentCodeValid) {
                    // 渲染成功,更新有效代码缓存
                    setLastValidCode(code);
                    setHasError(false);
                    chartContainerRef.current.innerHTML = svg;
                } else {
                    // 解析出错,渲染上一次的正确SVG
                    if (lastValidCode) {
                        const { svg: validSvg } = await mermaid.render('mermaid-chart', lastValidCode);
                        chartContainerRef.current.innerHTML = validSvg;
                    } else {
                        // 没有历史正确代码时,清空容器
                        chartContainerRef.current.innerHTML = '';
                    }
                }
            } catch (err) {
                setHasError(true);
                setErrorMessage(err?.message || '渲染失败');
                handleMessage?.(err?.message);
                // 出错时复用历史正确代码
                if (lastValidCode) {
                    mermaid.render('mermaid-chart', lastValidCode).then(({ svg }) => {
                        chartContainerRef.current.innerHTML = svg;
                    });
                }
            } finally {
                // 恢复原始的解析错误回调,避免影响其他组件
                mermaid.parseError = originalParseError;
            }
        };

        renderChart();

    }, [code, lastValidCode, handleMessage]);

    return (
        <div className="content">
            <div 
                ref={(el) => {
                    chartContainerRef.current = el;
                    if (ref) ref.current = el;
                }} 
                className="mermaid"
            ></div>
            {/* 可选:显示错误提示 */}
            {hasError && <div className="mermaid-error">{errorMessage}</div>}
        </div>
    );
});

export default Mermaid;

关键优化点说明:

  • 手动控制渲染:关闭startOnLoad,使用mermaid.render方法手动触发渲染,完全控制渲染流程和结果。
  • 状态简化:只保留lastValidCode(上一次正确的代码)、hasError(是否出错)、errorMessage(错误信息)三个核心状态,逻辑更清晰。
  • 错误处理闭环:
    1. 解析出错时标记isCurrentCodeValid为false,不更新有效代码缓存。
    2. 渲染失败时,优先复用lastValidCode生成SVG并渲染。
    3. 没有历史正确代码时,清空容器避免显示错误SVG。
  • 避免全局污染:临时覆盖mermaid.parseError后,在finally中恢复原始回调,防止影响其他Mermaid组件。
  • React范式兼容:使用useRef获取容器元素,替代getElementById,符合React的组件生命周期逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:17:27