单页应用中重绘或重新初始化windyAPI:路由切换后地图无法加载问题
问题原因
你当前的问题根源是windyInit仅在页面首次加载时执行1次,仅会绑定首次渲染的id为windy的DOM节点。路由切换时地图组件会被卸载,原有windy节点被销毁,切回路由后新渲染的windy节点没有被重新执行初始化逻辑,因此无法显示地图。
解决方案
步骤1:修改index.html代码
删掉head中手动调用windyInit的代码,仅保留两个SDK的引入,修改后的head相关代码如下:
<!DOCTYPE html> <html lang="en"> <head> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script> <script src="https://api.windy.com/assets/map-forecast/libBoot.js"></script> </head> <body> <div id="root"></div> </body> </html>
步骤2:重写地图组件逻辑
在组件挂载时触发Windy初始化,卸载时清理实例避免内存泄漏,修改后的组件代码如下:
import { useEffect } from 'react'; const ReportMap = () => { useEffect(() => { // 兜底判断,避免SDK未加载完成时报错 if (!window.windyInit) return; let mapInstance = null; // 组件挂载时初始化地图 windyInit({ key: "KL", container: "windy" // 明确指定绑定的DOM id }, (windyAPI) => { mapInstance = windyAPI.map; // 可在此处添加其他地图配置逻辑,比如初始中心点、缩放层级等 }); // 组件卸载时清理实例 return () => { if (mapInstance) { mapInstance.remove(); mapInstance = null; } // 清空容器内容避免残留 const windyContainer = document.getElementById('windy'); if (windyContainer) windyContainer.innerHTML = ''; } }, []); // 空依赖保证仅在组件挂载、卸载时触发执行 return ( <div> <div id="windy" style={{width: "100%", height: "96vh"}}></div> </div> ); }; export default ReportMap;
注意事项
- 若出现初始化时
windyInit未定义的报错,可给libBoot.js的script标签添加onload事件回调触发初始化,或在组件内加短时间轮询判断SDK加载状态。 - 不要全局永久保留Windy实例引用,每次组件挂载都重新初始化对应新DOM节点,避免实例与DOM绑定错位。
- 若使用React18严格模式,useEffect会默认执行两次,可在初始化前先判断
windy容器是否已有渲染内容,避免重复初始化冲突。
内容的提问来源于stack exchange,提问作者sania
相关产品推荐
相关产品推荐

