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
相关产品推荐
相关产品推荐

