Search code examples
reactjsgoogle-mapsreact-google-maps-api

how to re-center react-google-maps on adding marker


I'm using @react-google-maps/api to show a few markers in a map.

I want to add another marker on button click, and when the marker has been added, I want the map to be centered so it shows all the markers. According to this, this is what I wrote:

const center = {
  lat: 55.378,
  lng: 3.436
};

const containerStyle = {
    borderRadius: '10px',
    width: '100%',
    height: '100%'
}

function Map(props) {
    const [map, setMap] = useState();
    const [markers, setMarkers] = useState([
        {
            lat: 51.378, 
            lng: 3.436
        }, 
        {
            lat: 47.0902, 
            lng: -125.712
        }
    ]);

    useEffect(() => {
        var bounds = new window.google.maps.LatLngBounds();
        for(var i = 0; i < markers.length; i++) {
            bounds.extend( new window.google.maps.LatLng(markers[i].lat, markers[i].lng));
        }

        map.fitBounds(bounds)
    }, [markers])

    const onLoad = React.useCallback(function callback(map) {
    const bound = new window.google.maps.LatLngBounds();
        setBounds(bound)
    map.fitBounds(bound);
    setMap(map)
  }, [])

  return (
        <>
    <div className={props.className}>
            <LoadScript
                googleMapsApiKey="API_KEY"
            >
                <GoogleMap
                    mapContainerStyle={containerStyle}
                    center={center}
                    zoom={10}
                    onLoad={onLoad}
                >
                {
                    markers.map((item) => {
                        return (
                            <Marker animation="DROP" position={{lat: item.lat, lng: item.lng}}/>
                        )
                    })
                }
                </GoogleMap>
            </LoadScript>
        </div>
        <button onClick={(e) => { e.preventDefault(); console.log("hehe"); const hoho = [...markers, {lat: 59.913, lng: 10.752}]; setMarkers(hoho)}}>Add marker</button>
        </>
    )
}

But when I run the code, this is the error I get:

TypeError: Cannot read properties of undefined (reading 'maps').

It is this line in the useEffect that is giving me the error:

var bounds = new window.google.maps.LatLngBounds();

How can I get a correct value of bounds? I tried to make a state variable and update the value once I got it in onLoad(), but that didn't work either. How can I fix this?


Solution

  • Your useEffect is executing before <LoadScript> has loaded the API. I would do something like:

    useEffect(() => {
      if (map) {
        var bounds = new window.google.maps.LatLngBounds();
        for(var i = 0; i < markers.length; i++) {
          bounds.extend( new window.google.maps.LatLng(markers[i].lat, markers[i].lng));
        }
        map.fitBounds(bounds)
      }
    }, [markers, map])
    

    map will only be defined if the API, window.google.maps.*** has been loaded.