React Leaflet 地图调整大小问题

问题描述 投票:0回答:1

在使用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='&copy; <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

reactjs react-hooks leaflet react-leaflet
1个回答
0
投票

根据文档

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;
};

记得调整您项目的代码,祝你好运

© www.soinside.com 2019 - 2024. All rights reserved.