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

React集成Forge Viewer加载Markups时的重渲染与缓存异常问题

问题分析与解决方案

初始代码的问题

  • 清理逻辑错误:useEffect的返回清理代码里,误把removeEventListener写成了addEventListener,组件卸载时没移除事件监听,重复绑定会引发不必要的重渲染和事件触发。
  • 事件循环触发:在EVENT_EDITMODE_ENTER回调里调用leaveEditMode(),会导致事件反复触发,进而引发组件持续重渲染。

更新后代码的问题及修复

当前用TOOL_CHANGE_EVENT实现后功能基本正常,但无法加载最新markups的核心原因:

  • 回调函数捕获的是markupsData的闭包旧值,当markupsData更新时,旧的监听回调还是用之前的数据,不会自动同步最新值。
  • 加载新markups前没清除原有标记层,旧内容残留导致新内容无法正常覆盖。

修复后的代码示例

React.useEffect(() => {
  const handleToolChange = async (x) => {
    if (!viewer.current) return;
    const extension = (await viewer.current.loadExtension("Autodesk.Viewing.MarkupsCore")) as any;
    // 仅在切换到标记工具且有有效markups数据时执行
    if (x.active && x.toolName === "markups.core" && markupsData?.id) {
      await extension.leaveEditMode();
      // 先清除原有标记层,避免旧内容残留
      extension.clearMarkups("layer_1");
      // 加载最新的markups字符串
      await extension.loadMarkups(markupsData.markupsString, "layer_1");
      await extension.enterEditMode("layer_1");
    }
  };

  const viewerInstance = viewer.current;
  viewerInstance?.addEventListener(Autodesk.Viewing.TOOL_CHANGE_EVENT, handleToolChange);

  // 清理函数:移除事件监听,避免内存泄漏和旧回调残留
  return () => {
    viewerInstance?.removeEventListener(Autodesk.Viewing.TOOL_CHANGE_EVENT, handleToolChange);
  };
}, [viewer.current, markupsData]); // 依赖项添加markupsData,确保数据更新时重新绑定监听

额外优化建议

  1. 缓存MarkupsCore扩展实例:避免每次事件触发都重新加载扩展,提升性能
const [markupsExt, setMarkupsExt] = React.useState(null);

React.useEffect(() => {
  if (!viewer.current) return;
  viewer.current.loadExtension("Autodesk.Viewing.MarkupsCore").then(ext => setMarkupsExt(ext));
}, [viewer.current]);

// 后续直接使用markupsExt即可,无需重复加载
  1. 主动触发markups更新:如果需要在markupsData更新时立即刷新(无需等待工具切换),可以单独加一个useEffect处理
React.useEffect(() => {
  if (!markupsExt || !markupsData?.id) return;
  const updateMarkups = async () => {
    await markupsExt.leaveEditMode();
    markupsExt.clearMarkups("layer_1");
    await markupsExt.loadMarkups(markupsData.markupsString, "layer_1");
    // 如果当前正处于标记工具模式,重新进入编辑模式
    if (viewer.current?.getActiveTool() === "markups.core") {
      await markupsExt.enterEditMode("layer_1");
    }
  };
  updateMarkups();
}, [markupsExt, markupsData]);

这样就能确保无论是否切换工具,只要markupsData更新,就能加载最新的标记内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:35:24