布局变更时地图Resize失效问题求助
解决侧边栏折叠后Mapbox地图右侧留白的问题
核心问题在于你用的Mapbox(react-map-gl底层依赖)只监听窗口resize事件,不会自动感知父容器的尺寸变化。当侧边栏通过动画收缩/展开时,地图容器的宽度已经改变,但地图本身没有重新计算尺寸,导致右侧留白。
下面是两种可靠的解决方法:
方法1:监听侧边栏过渡结束事件触发地图resize
利用CSS过渡的transitionend事件,在侧边栏动画真正完成后再调用地图的resize()方法,比固定延时更准确。
代码示例
import React, { useRef } from 'react'; import { Map, Marker } from 'react-map-gl'; function Root() { const [expanded, setExpanded] = React.useState(true); const mapRef = useRef(null); const toggle = () => { setExpanded(prev => !prev); }; // 侧边栏过渡结束后触发地图resize const handleTransitionEnd = () => { mapRef.current?.resize(); }; return ( <div style={{ display: "flex", height: "100vh" }}> <div style={{ width: expanded ? 700 : 100, background: "red", transition: "width 0.3s ease" // 确保过渡动画生效 }} onTransitionEnd={handleTransitionEnd} > <button onClick={toggle}>Toggle</button> </div> <Map ref={mapRef} initialViewState={{ latitude: 37.8, longitude: -122.4, zoom: 14, }} style={{ width: "100%", height: "100%" }} mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json" > <Marker longitude={-122.4} latitude={37.8} color="red" /> </Map> </div> ); }
方法2:用ResizeObserver监听地图容器尺寸变化
如果侧边栏的尺寸变化可能由多种触发方式(比如窗口resize、其他组件交互),用ResizeObserver监听地图容器的尺寸变化,只要容器大小改变就自动触发地图resize,通用性更强。
代码示例
import React, { useRef, useEffect } from 'react'; import { Map, Marker } from 'react-map-gl'; function Root() { const [expanded, setExpanded] = React.useState(true); const mapRef = useRef(null); const mapContainerRef = useRef(null); const toggle = () => { setExpanded(prev => !prev); }; useEffect(() => { const observer = new ResizeObserver(() => { mapRef.current?.resize(); }); if (mapContainerRef.current) { observer.observe(mapContainerRef.current); } // 组件卸载时清理监听 return () => { mapContainerRef.current && observer.unobserve(mapContainerRef.current); }; }, []); return ( <div style={{ display: "flex", height: "100vh" }}> <div style={{ width: expanded ? 700 : 100, background: "red", transition: "width 0.3s ease" }} > <button onClick={toggle}>Toggle</button> </div> <div ref={mapContainerRef} style={{ width: "100%", height: "100%" }}> <Map ref={mapRef} initialViewState={{ latitude: 37.8, longitude: -122.4, zoom: 14, }} style={{ width: "100%", height: "100%" }} mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json" > <Marker longitude={-122.4} latitude={37.8} color="red" /> </Map> </div> </div> ); }
为什么之前的延时方案不好?
固定延时和实际动画时长可能存在偏差(比如浏览器性能波动导致动画变慢),会出现短暂留白。而transitionend事件是动画真正完成时触发,ResizeObserver能精准捕捉容器尺寸变化,这两种方法都能让地图resize更流畅。
内容的提问来源于stack exchange,提问作者zimnykisiel
相关产品推荐
相关产品推荐

