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

Autodesk Viewer React组件重渲染后无法完全关闭报错排查

Autodesk Viewer在React组件卸载后报错:Cannot read properties of null (reading 'updateMaterials')

在React组件中集成Autodesk Viewer时,组件重渲染后Viewer无法完全销毁。已在componentDidMount中初始化Viewer,在componentWillUnmount中执行finish()并将viewer置空,但仍出现错误:TypeError: Cannot read properties of null (reading 'updateMaterials')。尝试添加impl.unloadCurrentModel()也无效果,使用的是Autodesk官方React示例组件,相关代码如下:

componentDidMount() {
  initializeViewerRuntime(this.props.runtime || {})
    .then(_ => {
      console.log('VIEWER HAS STARTED');
      this.viewer = new Autodesk.Viewing.GuiViewer3D(this.container);
      **this.viewer.start();**
      this.viewer.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, this.onViewerCameraChange);
      this.viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, this.onViewerSelectionChange);
      this.updateViewerState({});
      console.log('THIS VIEWER', this.viewer);
    })
    .catch(err => console.error(err));
}

componentWillUnmount() {
  if (this.viewer) {
    console.log('VIEWER HAS STOPPED');
    this.viewer.removeEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, this.onViewerCameraChange);
    this.viewer.removeEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, this.onViewerSelectionChange);
    this.viewer.finish();
    this.viewer = null;
  }
}

解决方法

  • 卸载前先移除所有自定义事件监听器,再卸载所有加载的模型并等待完成
  • 停止Viewer内部的渲染循环,避免后续异步回调执行
  • 清理Viewer容器的DOM元素,移除残留的渲染内容
  • 改用异步卸载逻辑,确保所有操作完成后再置空viewer引用

修改后的componentWillUnmount代码:

async componentWillUnmount() {
  if (!this.viewer) return;

  console.log('VIEWER HAS STOPPED');
  // 移除自定义事件监听器
  this.viewer.removeEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, this.onViewerCameraChange);
  this.viewer.removeEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, this.onViewerSelectionChange);

  // 卸载所有已加载的模型
  const models = this.viewer.impl.modelQueue().getModels();
  for (const model of models) {
    await this.viewer.unloadModel(model);
  }

  // 停止渲染循环
  this.viewer.impl.stopRenderLoop();

  // 销毁Viewer实例
  this.viewer.finish();

  // 清理容器DOM
  while (this.container.firstChild) {
    this.container.removeChild(this.container.firstChild);
  }

  this.viewer = null;
}

错误原因是Viewer内部的渲染循环或异步回调在组件卸载后仍在运行,此时viewer引用已被置空,导致访问null的updateMaterials属性。通过上述步骤,能确保Viewer完全停止所有后台操作后再销毁引用,避免空指针错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:43:31