1

I have this react component:

import React, { Fragment } from 'react';
import L from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

const customMarker = new L.icon({
    iconUrl: '/images/poemEditorTools/location-pointer-new.svg',
    iconSize: [56, 72],
    iconAnchor: [26, 72],
}); 

const MyPopupMarker = ({ content, position }) => (
    <Marker position={position} icon={customMarker} >
      <Popup>{content}</Popup>
    </Marker>
)

const MyMarkersList = ({ markers }) => {
    const items = markers.map(({ key, ...props }) => (
        <MyPopupMarker key={key} {...props} />
    ))
    return <Fragment>{items}</Fragment>
}

const markers = [
    { key: 'marker1', position: [51.5, -0.1], content: 'My first popup' },
    { key: 'marker2', position: [51.51, -0.1], content: 'My second popup' },
    { key: 'marker3', position: [51.49, -0.05], content: 'My third popup' },
]

class MapWithPoems extends BaseComponent {
    render() {
        return (
            <Map center={[51.505, -0.09]} zoom={13} style={{ height: "500px", width: "100%" }} >
                <TileLayer
                    url={
                        "https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"
                    }
                />
                <MyMarkersList markers={markers} />
            </Map>
        );
    }
}

export default MapWithPoems;

The problem is when the page is downloaded the map is shrinket to the left side of the container. I have to resize the window to make the map to show up in the full width. See images.

enter image description here

enter image description here

What is wrong here? :)

podeig
  • 2,597
  • 8
  • 36
  • 60

3 Answers3

4

You have to call map.invalidateSize(); after init the map.

Maybe this link can help you to use it in reactjs: https://stackoverflow.com/a/56184369/8283938

Falke Design
  • 10,635
  • 3
  • 15
  • 30
  • Thank you! :) I have to do this. componentDidMount() { const map = this.mapRef.current.leafletElement; setTimeout(() => { map.invalidateSize(); }, 250); } Needed to add timeout before .invalidateSize() – podeig Jan 22 '20 at 10:07
  • @podeig Map has an event 'wenReady', you might want to use that instead of a timer. Add it along with your 'zoom' and 'style' props, ```whenReady={() => { console.log('Map is ready...add stuff here :-)'); }}``` – Will59 Mar 10 '20 at 10:44
1

using react hooks. This worked:

const map = useMap()

useEffect(() => {
    setTimeout(() => { 
        map.invalidateSize(); 
    }, 250); 
}, [map])

But the solution seems a bit hacky to me. 250ms seems arbitrary.

kari
  • 11
  • 1
1

Using react hooks, without setTimeout(). This implementation worked for me.

const setMap = ( map: LeafletMap ) => {
        const resizeObserver = new ResizeObserver( () => {
                map.invalidateSize()
        })
        const container = document.getElementById('map-container')
        resizeObserver.observe(container!)
}


<MapContainer
...other properties
id='map-container'
whenCreated={setMap}

>

</MapContainer>

whenCreated allows you to use the map instance as argument to the function please check this react-leaflet documentation.

I got the idea of using ResizeObersver from Michael MacFadden's StackOverflow answer

FaitAccompli
  • 787
  • 5
  • 16