Next.js中google.maps.OverlayView重渲染元素列表时出现NotFoundError
问题原因分析
当trips状态变化触发组件重渲染时,出现NotFoundError的核心原因是React与谷歌地图OverlayView对DOM节点的管理权冲突:
- 你创建的弹窗DOM节点最初由React渲染并管理,当通过OverlayView挂载到地图上时,谷歌地图的脚本会将这个DOM节点从React的DOM树中移除,插入到地图自身的容器节点(如
mapPane)中。 - 当
trips更新引发重渲染,React会对比虚拟DOM与真实DOM,发现它原本管理的弹窗节点已经不在预期的父元素下,于是尝试执行removeChild操作,但此时该节点的父元素已经是地图容器,而非React渲染的节点,导致报错。 - 注释弹窗创建后,没有DOM节点被外部脚本(谷歌地图)移动,React重渲染时能正常匹配虚拟DOM与真实DOM,因此错误消失。
解决方案建议
用useEffect管理OverlayView生命周期
每次trips更新时,先销毁旧的OverlayView实例:调用overlay.setMap(null),让谷歌地图自动清理对应的DOM节点,再创建新的OverlayView实例绑定新的行程数据。脱离React的DOM管理
不要让React直接渲染弹窗DOM,而是通过useRef手动创建DOM元素,将其交给OverlayView管理,避免React跟踪这些节点的位置变化。示例逻辑:const popupRef = useRef(null); useEffect(() => { if (!popupRef.current) { popupRef.current = document.createElement('div'); // 给popupRef.current添加内容样式 } // 创建OverlayView并挂载popupRef.current const overlay = new google.maps.OverlayView(); // ... 其他OverlayView逻辑 return () => { overlay.setMap(null); // 清理 }; }, [trips]);批量清理旧弹窗
在加载新页面前,遍历所有已创建的OverlayView实例,调用setMap(null)销毁,确保旧的弹窗DOM节点被谷歌地图完全清理,避免残留节点干扰React重渲染。
内容的提问来源于stack exchange,提问作者Flov
相关产品推荐
相关产品推荐

