React-Leaflet点击按钮修改地图宽度无效问题求助
如何在react-leaflet中点击按钮调整地图尺寸?
我在用react-leaflet开发地图应用,希望点击按钮时在地图左侧显示菜单,实现方式是将地图宽度从100%调整为80%。菜单按钮用于切换isMenuOn布尔值状态,预期地图会随按钮点击重新渲染并调整尺寸。
现有代码
App.js
export default function App() { const [isMarkerClick, setIsMarkerClick] = React.useState(false); const [isMenuOn, setIsMenuOn] = React.useState(false); function toggleMarker() { setIsMarkerClick(prevClick => !prevClick); } function toggleMenu() { setIsMenuOn(prevMenu => !prevMenu); } return ( <div> <MainMap isMenuOn={isMenuOn} /> <MarkerButton isMarkerClick={isMarkerClick} toggleMarker={toggleMarker} /> <MenuButton toggleMenu={toggleMenu} /> </div> ) }
MainMap组件
export default function MainMap(props) { const isMenuOn = props.isMenuOn; const isMarkerClick = props.isMarkerClick; const zoom = 15; const position = ['39.9526', '-75.1652']; const [marker, setMarker] = React.useState(["", ""]) return ( <div> <MapContainer center={position} zoom={zoom} zoomControl={false} style={{ height: "100vh", width: isMenuOn ? "80vw" : "100vw" }} > <TileLayer attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <Marker position={marker}></Marker> {isMarkerClick && <ClickTrack setMarker={setMarker} />} </MapContainer> </div> ) }
目前点击菜单按钮后,isMenuOn状态已更新并传递给MapContainer,但地图并未重新渲染调整宽度。
解决方案
问题出在react-leaflet的MapContainer组件特性上:当容器尺寸变化时,Leaflet底层不会自动感知并调整地图,必须手动调用地图实例的invalidateSize()方法触发重绘。
修改MainMap组件,步骤如下:
- 导入react-leaflet提供的
useMap钩子,获取Leaflet地图实例 - 使用
useEffect监听isMenuOn的状态变化,状态改变时调用invalidateSize()
修改后的MainMap代码:
import { useMap } from 'react-leaflet'; // 新增导入 export default function MainMap(props) { const isMenuOn = props.isMenuOn; const isMarkerClick = props.isMarkerClick; const zoom = 15; const position = ['39.9526', '-75.1652']; const [marker, setMarker] = React.useState(["", ""]) const map = useMap(); // 获取地图实例 // 监听isMenuOn变化,触发地图尺寸重算 React.useEffect(() => { if (map) { map.invalidateSize(); } }, [isMenuOn, map]); // 依赖项包含isMenuOn和map return ( <div> <MapContainer center={position} zoom={zoom} zoomControl={false} style={{ height: "100vh", width: isMenuOn ? "80vw" : "100vw" }} > <TileLayer attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <Marker position={marker}></Marker> {isMarkerClick && <ClickTrack setMarker={setMarker} />} </MapContainer> </div> ) }
这样每次点击菜单按钮切换isMenuOn状态时,地图容器宽度变化后,会自动调用invalidateSize()让Leaflet重新计算地图尺寸,从而正确渲染出调整后的地图宽度。
内容的提问来源于stack exchange,提问作者etmarkwalter
相关产品推荐
相关产品推荐

