在使用react-leaflet创建地图时,我希望地图组件占据页眉和页脚之后的所有可用空间。该代码似乎有效。但是,当触发调整大小处理程序时,地图组件的大小没有改变。有什么建议的修复方法吗?
CodeSandbox 链接位于底部。
import React, { useState, useEffect, useRef } from "react";
import { MapContainer, TileLayer } from "react-leaflet";
import "leaflet/dist/leaflet.css";
const MyMap = () => {
const mapRef = useRef(null);
const [windowHeight, setWindowHeight] = useState(150);
const [loading, setLoading] = useState(true);
useEffect(() => {
const handleResize = () => {
const headerHeight = document.querySelector("header").offsetHeight;
const footerHeight = document.querySelector("footer").offsetHeight;
console.log(
window.innerHeight,
headerHeight,
document.querySelector("header"),
footerHeight
);
setWindowHeight(window.innerHeight - headerHeight - footerHeight - 16);
if (mapRef) {
console.log("map exist", windowHeight, mapRef.current);
}
setLoading(false);
};
window.setTimeout(handleResize, 1000);
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return (
<div style={{ display: "flex", flexDirection: "column" }}>
<header>
<h1>HEADER</h1>
</header>
{loading && <div>loading...</div>}
<main style={{ flex: "1 1 auto" }}>
{!loading && (
<MapContainer
center={[51.505, -0.09]}
zoom={13}
style={{ height: `${windowHeight}px` }}
ref={mapRef}
>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
</MapContainer>
)}
</main>
<footer>
<h1>Footer</h1>
</footer>
</div>
);
};
export default MyMap;
https://codesandbox.io/embed/lknkgg?view=editor+%2B+preview&module=%2Fsrc%2FMyApp.js
Except for its children, MapContainer props are immutable: changing them after they have been set a first time will have no effect on the Map instance or its container.
这意味着更改样式的高度不会产生任何效果。一个快速但肮脏的解决方案是通过设置一个键来强制重新渲染,例如
<MapContainer
center={[51.505, -0.09]}
zoom={13}
style={{ height: `${windowHeight}px` }}
key={windowHeight}
ref={mapRef}
>
但是我不会推荐这个。我确实检查了我的旧代码并找到了解决方法:
MapContainer 的子组件可以访问地图,从而可以使大小无效。
<MapContainer
center={position ? position : [61, 15]}
zoom={zoom}
scrollWheelZoom={true}
style={{ height: height, width: "100%", zIndex: 94 }}
minZoom={4}
maxZoom={18}
preferCanvas
>
<MapReziser width={rect.width} height={rect.height} />
.
.
.
</MapContainer>
MapReziser 应该是一个可以访问地图的组件,并且当高度变化时使尺寸无效。
const MapReziser: React.FC<{ width: number; height: number }> = ({
width,
height,
}) => {
const map = useMap();
useEffect(() => {
if (width > 0 && height > 0) {
// If size is changed the map will have render issues
// e.g. two maps in different tabs or a map in a accordion
// To solve this we monitor the size of the map and invalidate the size on change
// This will cause the map to rerender and fix the issue
// However this will cause issues with open popups
// To solve this we fly to the current center of the map
map.invalidateSize();
map.flyTo(map.getCenter());
}
}, [map, width, height]);
return null;
};
记得调整您项目的代码,祝你好运