PaulLeCam / react-leaflet

React components for Leaflet maps
https://react-leaflet.js.org
Other
5.14k stars 885 forks source link

Map grays out while adjusting the size #1074

Open vardhan03 opened 1 year ago

vardhan03 commented 1 year ago

Bug report in v4

Thanks to this library, it is very useful. But with the new version 4.2.1, I am facing an issue with the map. The map will gray out when we try to adjust its size of it i.e. expanding the view horizontally/ vertically as below. This is while the map initially loaded i.e. image After maximizing the map view, it looks as below i.e. image

In version 3.x, we had a workaround to this issue using whenCreated call back by setting the ref and invalidating the size. It used to work fine.

@PaulLeCam, can you please let me know what approach we need to follow to fix this issue in v4? I tried using the ref attribute to the map, but the issue still persists.

tinncdev commented 1 year ago

Same problems here, the map also not center things correctly after resize the container My current solution is listen to the container size via ResizeObserver, when it changes, tell the map to re-check its size with map.invalidateSize() (or simplier listen on windows resize event if your map size only depends on it).

import React, { useEffect, useRef } from 'react';
import { MapContainer, TileLayer } from 'react-leaflet';

const CustomMap = () => {
  const mapRef = useRef(null);
  const containerRef = useRef(null);

  useEffect(() => {
    const map = mapRef.current;

    const container = containerRef.current;
    const resizeObserver = new ResizeObserver(() => {
      if (map) {
        map.invalidateSize();
      }
    });

    resizeObserver.observe(container);

    return () => {
      resizeObserver.unobserve(container);
    };
  }, []);

  return (
    <div ref={containerRef} style={{ width: '100%', height: '400px' }}>
      <MapContainer center={[51.505, -0.09]} zoom={13} ref={mapRef}>
        <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
      </MapContainer>
    </div>
  );
};

export default CustomMap;
rabbl commented 7 months ago

This solution does not work for react-leaflet v3 and v4. But the ref to the map can be retrieved by a child-component and the useMap-hook:

const MapRef = ({mapRef}) => {
  const map = useMap();
  useEffect(() => {
    if (map) {
      mapRef.current = map;
    }
    return () => {
      mapRef.current = null;
    };
  }, [map]);

  return null;
};

<MapContainer
        center={coords}
        zoom={13}
        scrollWheelZoom={false}
        wheelDebounceTime={100}
>
        <MapRef mapRef={mapRef}/>
        <TileLayer url="https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"/>
</MapContainer>