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

React+TS环境下Autodesk Forge Viewer AggregatedView初始化失败求助

解决Autodesk Forge AggregatedView初始化时的Cannot read properties of null错误

问题背景

尝试通过React组件使用AggregatedView初始化Forge Viewer并加载多模型时,在await view.init(refElement, options3d)处触发错误:Cannot read properties of null (reading 'getBoundingClientRect')。

错误原因

  • 传递给初始化函数的是React useRef对象本身,而非实际DOM元素(ref.current),导致view.init无法获取有效的渲染节点
  • 未在初始化前校验DOM元素是否已完成挂载,组件挂载阶段ref.current为null,直接调用初始化会引发空指针异常

解决方案

1. 修改React组件的useEffect逻辑

确保传递DOM元素而非ref对象,增加DOM存在校验,并添加清理函数避免内存泄漏:

import { initializeViewer } from "./Aggregated-helper"
import { useEffect, useRef } from 'react'
declare var Autodesk: any

export interface ForgeViewerProps {
  urn: string
  accessToken: string
}

const models = [
  { urn: 'urn:dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLktmSE5VSkFSUklxdE53RnZUM2o2MUE_dmVyc2lvbj0x' },
  { urn: 'urn:dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLllhbk0wUHZxVGFLVnJJbnJKSG9OaFE_dmVyc2lvbj0z' }
];

const AggregatedViewer = (props: ForgeViewerProps) => {
  const { accessToken } = props
  const viewer3DRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!accessToken || !viewer3DRef.current || !Autodesk) {
      console.log("缺少必要参数或DOM未挂载")
      return
    }
    initializeViewer(viewer3DRef.current, models, accessToken)
    
    // 组件卸载时清理Viewer实例,避免内存泄漏
    return () => {
      if (window.viewer) {
        window.viewer.finish()
        window.viewer = null
      }
    }
  }, [accessToken])

  return(
    <>
      <div
        ref={viewer3DRef}
        className="ForgeViewer"
        style={{ height: "100vh", width: "100%" }}
      ></div>
    </>
  ) 
}

export default AggregatedViewer

2. 修改辅助函数的初始化逻辑

添加DOM元素有效性校验,增加错误捕获,并优化模型加载流程:

declare var Autodesk: any
export const initializeViewer = async (refElement: HTMLElement, models: Array<{ urn: string }>, accessToken: string) => {
  // 先校验DOM元素是否有效
  if (!refElement) {
    console.error("无法获取有效的DOM元素用于初始化Viewer")
    return
  }

  const options = {
    env: "AutodeskProduction",
    accessToken: accessToken,
    api:'derivativeV2'
  }

  const options3d = {
    viewerConfig: {
      disableBimWalkInfoIcon: true
    }
  };

  Autodesk.Viewing.Initializer(options, async function () {
    const view = new Autodesk.Viewing.AggregatedView();
    try {
      // 初始化AggregatedView
      await view.init(refElement, options3d)
      // 将viewer实例挂载到window方便调试和清理
      window.viewer = view.viewer

      // 批量加载模型文档
      const tasks = models.map(md => loadManifest(md.urn))
      const docs = await Promise.all(tasks)
      
      // 提取有效的3D几何节点
      const validBubbles = docs.flatMap(doc => {
        const bubbles = doc.getRoot().search({ type: 'geometry', role: '3d' });
        return bubbles.length > 0 ? [bubbles[0]] : []
      })

      if (validBubbles.length > 0) {
        await view.setNodes(validBubbles)
      } else {
        console.error("没有找到可加载的3D模型节点")
      }
    } catch (err) {
      console.error("初始化AggregatedView或加载模型失败", err)
    }
  })

  function loadManifest(documentId: string) {
    return new Promise<any>((resolve, reject) => {
      const onDocumentLoadSuccess = (doc: any) => {
        // 下载AEC模型数据(针对建筑类模型)
        doc.downloadAecModelData(() => resolve(doc));
      };
      const onDocumentLoadFailure = (err: any) => {
        console.error(`加载文档${documentId}失败`, err)
        reject(err)
      }
      Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
    })
  }
}

3. 额外注意事项

  • 确保已在页面中正确加载Forge Viewer的脚本和样式,例如在public/index.html中添加:
    <link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css">
    <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
    
  • 确保accessToken拥有读取指定模型URN的权限
  • 避免重复初始化Viewer,通过accessToken作为useEffect的依赖项,确保仅当token变化时重新初始化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 14:47:32