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

如何在React弹窗首次打开时直接渲染Mermaid流程图?

解决React Modal首次打开时Mermaid图表不立即渲染的问题

你的代码中首次打开Modal时Mermaid脚本先显示为字符串,是因为mermaid.contentLoaded()的执行时机早于Modal内的.mermaid元素完成挂载,导致Mermaid无法识别并渲染目标元素。

修改方案

通过React的useRef获取目标DOM元素,在Modal确认打开且元素存在后,手动触发Mermaid的渲染逻辑,确保元素就绪后再处理。

修改后的完整代码

import React, { useState, useRef, useEffect } from "react";
import Button from "@mui/material/Button";
import Modal from "@mui/material/Modal";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import mermaid from "mermaid";

mermaid.initialize({ startOnLoad: true });

export default function Popup() {
  const [open, setOpen] = useState(false);
  // 创建ref用于获取mermaid容器元素
  const mermaidContainerRef = useRef(null);

  const handleClickOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  const mermaidScript = `sequenceDiagram
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!
    Alice-)John: See you later!
  `;

  useEffect(() => {
    // 当Modal打开且容器元素存在时,手动渲染mermaid图表
    if (open && mermaidContainerRef.current) {
      mermaid.init(undefined, mermaidContainerRef.current);
    }
  }, [open]);

  return (
    <div>
      <Button variant="contained" onClick={handleClickOpen}>
        Open Modal
      </Button>
      <Modal
        open={open}
        onClose={handleClose}
        aria-labelledby="modal-modal-title"
        aria-describedby="modal-modal-description"
      >
        <Box
          sx={{
            height: "90%",
            width: "90%",
            position: "absolute",
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            bgcolor: "background.paper",
            border: "2px solid #000",
            boxShadow: 24,
            p: 4
          }}
        >
          <Typography id="modal-modal-title" variant="h6" component="h2">
            Mermaid Diagram
          </Typography>
          <Typography id="modal-modal-description" sx={{ mt: 2 }}>
            {/* 将ref绑定到mermaid容器 */}
            <div 
              ref={mermaidContainerRef}
              className="mermaid" 
              style={{ height: "70%", width: "70%" }}
            >
              {mermaidScript}
            </div>
          </Typography>
        </Box>
      </Modal>
    </div>
  );
}

关键说明

  1. useRef获取DOM元素:确保能直接访问到Modal内的Mermaid容器,避免依赖全局DOM扫描。
  2. 精准触发渲染:在useEffect中监听open状态变化,仅当Modal打开且容器元素存在时,调用mermaid.init()手动渲染目标元素,保证DOM就绪后再执行渲染逻辑。

你也可以改用MUI Modal的onOpen回调替代useEffect,效果一致:

<Modal
  open={open}
  onClose={handleClose}
  onOpen={() => {
    if (mermaidContainerRef.current) {
      mermaid.init(undefined, mermaidContainerRef.current);
    }
  }}
  aria-labelledby="modal-modal-title"
  aria-describedby="modal-modal-description"
>
  {/* ... 其余代码不变 */}
</Modal>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 03:17:14