0

I have a FeatureGroup with a Circle inside of it. On load, I want the map's viewport to completely show the circle. There are a number of relevant StackOverflow questions (this one, another one, a third), and I have tried them all. None have worked for me using modern tools.

import { MapContainer, TileLayer, FeatureGroup, Circle } from 'react-leaflet'

export default function MyMap({volunteer, pollingPlaces}) {

    const coordinates = [40.781753, -73.966583];
    const circle = <Circle pathOptions={{color: 'purple'}} center={coordinates} radius={3*1609} />

    return (
        <MapContainer center={coordinates}
            style={{
                height:"400px",
                width: "400px"
            }}>
            <TileLayer
                attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />
            <FeatureGroup>
                {circle}
            </FeatureGroup>
        </MapContainer>
        )
}

One of the big problems is that string refs are now deprecated, and most of the old answers rely on this. It's also not clear to me how to use the new useMap hook in concert with the createRef method in a function component. (The third approach above seems to get the closest, and is from just a year ago, but it still relies on componentDidMount.) Finally, I am unable to get my FeatureGroup to call either the onadd or onAdd method (it's unclear which is correct? see comment below the answer…) when I pass it to the component. The 2018 answer relies on this callback.

The combination of these three issues mean I can't get any of the old solutions working. So I thought I'd ask anew: what's the right way to do this these days?

Nick K9
  • 3,885
  • 1
  • 29
  • 62

1 Answers1

4

For the question described in the title, as you have another one later regarding onAdd and it is better to ask it separately in my opinion, you can still use a ref to get a reference to the FeatureGroup

All you need is to call map.fitBounds. To get the map reference you need to use whenCreated prop inside the component that includes MapContainer. If you were inside a child you would have to use useMap hook to get it. Once you get this you need to use the featureGroup ref which is a react ref, an object actually, and can be accessed via current. Inside there you have some leaflet methods. The one you need is getBounds method to retrieve the bounds of your feature group.

const [map, setMap] = useState(null);
  const featureGroupRef = useRef();

  useEffect(() => {
    if (!map) return;
    map.fitBounds(featureGroupRef.current.getBounds());
  }, [map]);

 <MapContainer
      center={coordinates}
      zoom={6}
      style={{
        height: "400px",
        width: "400px"
      }}
      whenCreated={setMap}
 >
  ...

 <FeatureGroup ref={featureGroupRef}>{circle}</FeatureGroup>
</MapContainer>

Demo

kboul
  • 13,836
  • 5
  • 42
  • 53
  • 1
    Amazing, thank you! This worked right away. For posterity: `createRef` is the class component equivalent of `useRef`, so no surprise that my attempts to employ that in my function component were failing. – Nick K9 May 21 '21 at 11:46