我一直在阅读 v3 中的变更日志,我看到了一些更改。
Map 组件被 MapContainer 取代,其行为有所不同,其中 props 是不可变的 我想创建一个 MapContainer 并能够动态更新宽度和高度,例如当我用户最小化窗口或组件大小更改时。
如何在不杀死 MapContainer 并创建其他新容器的情况下执行此操作?
<MapContainer whenCreated={...} style={{width:xxx, height:yyy}}
使用地图的“invalidateSize”功能:
const { height } = useSize(container);
useEffect(() => {
if (map != null) {
map.invalidateSize();
}
}, [map, height]);
您可以将其放入地图的子级中,如另一个答案中所述,或者将其放在父级中,将地图作为 MapContainer 上的引用,这两种方式都可以。
MapContainer 只需要静态样式:
width: 100%;
height: 100%;
不再有问题了(终于)
迁移到 react-leaflet v3.x
后我遇到了同样的问题因此,我使用 react-leaflet
useMap
钩子做了一个技巧,并成功尝试根据其容器(无论它是什么以及窗口)调整地图大小。
所以我的地图容器代码如下所示:
function SetHeightOnChange({ height }) {
const map = useMap();
const mapContainer = map.getContainer();
mapContainer.style.cssText = `height: ${height}px; width: 100%; position: relative;`;
return null;
}
return (
<MapContainer
center={center}
zoom={13}
style={{
height: height + "px",
width: "100%",
}}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<CircleMarker center={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</CircleMarker>
<SetHeightOnChange height={height} />
</MapContainer>
);
注意:对于地图
width
,您只需将其设置为100%
即可。
另请注意
MapContainer
内的子组件,我将其命名为SetHeightOnChange
。 (确保将该子组件放置在 Marker
标签之后)。
现在,每当您在调整大小更改后触发高度值更新时,您的地图大小都会相应更改。
结合上面的答案,您可以使用自定义钩子来获取容器的大小
import { useState, useEffect } from "react"
export default function useSize(ref) {
const [size, setSize] = useState({})
useEffect(() => {
if (ref.current == null) return
const observer = new ResizeObserver(([entry]) => setSize(entry.contentRect))
observer.observe(ref.current)
return () => observer.disconnect()
}, [])
return size
}
创建另一个组件以在每次调整地图大小时获取新图块
import { useMap } from "react-leaflet";
const ResizeMap = ({ containerRef }) => {
const map = useMap();
const { width, height } = useSize(containerRef);
useEffect(() => {
if (map) {
setTimeout(() => {
map.invalidateSize();
}, 100);
}
}, [height, width]);
return null;
};
然后在您的地图中,您可以为容器分配一个引用,并将该引用传递给您的 ResizeMap 组件
const containerRef = useRef(null)
<div ref={containerRef} className="container">
<MapContainer
{...props}
style={{ width: "100%", height: "100%" }}
>
<ResizeMap containerRef = {containerRef} />
...
</MapContainer >
<div>
这样您就可以使用 .container 类中定义的任何样式来处理地图的大小