4

According to the React Google Maps library, you can call these four methods from the ref object.

What seems weird, is that these methods are supposed to receive two parameters, a map instance and other arguments, like so:

fitBounds(map, args) { return map.fitBounds(...args); }

However, when calling fitBounds() this way, nothing happens on the map, no bounds are changed and no errors are thrown. This is the way I have structured the component, calling fitBounds in componentDidUpdate:

import React from 'react'
import { withGoogleMap, GoogleMap, InfoWindow, Marker, OverlayView } from 'react-google-maps'
import InfoBox from 'react-google-maps/lib/addons/InfoBox'
import map from 'lodash/map'

// Higher-Order Component
const AllocatedPlacesMap = withGoogleMap(props => (
  <GoogleMap
    center={props.center}
    defaultZoom={4}
    options={{ scrollwheel: false, minZoom: 3, maxZoom: 15 }}
    onCenterChanged={props.onCenterChanged}
    ref={props.onMapMounted}>
    {props.markers.map((marker, index) => (
      <Marker
        key={index}
        position={marker.position}
      />
    ))}
  </GoogleMap>
));

class Map extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }

  getCenter = () => {
    this._bounds = new google.maps.LatLngBounds();

    this.props.markers.forEach((marker, index) => {
      const position = new google.maps.LatLng(marker.lat, marker.lng);
      this._bounds.extend(position);
    });

    return this._bounds.getCenter();
  }

  componentDidUpdate() {
    this._map.fitBounds(this._map, this._bounds);
  }

  handleMapMounted = (map) => {
    this._map = map;
  }

  render() {
    return (
      <div className="allocated-places">
        <AllocatedPlacesMap
          containerElement={
            <div style={{ height: `100%` }} />
          }
          mapElement={
            <div style={{ height: `100%` }} />
          }
          center={this.getCenter()}
          markers={props.markers}
          onMapMounted={this.handleMapMounted}
        />
      </div>
    )
  }
}

export default Map;

Any idea of what is the correct way to call fitBounds() in this case? documentation and examples seem to be lacking in this regard.

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Dan H
  • 3,524
  • 3
  • 35
  • 46
  • fitBounds() no longer requires a map instance as first parameter. This bug was also fixed in v9 of the library. – Dan H Dec 03 '17 at 23:23

2 Answers2

1

Looking at the function definition fitBounds(map, args) { return map.fitBounds(...args); } we can see that the spread operator is applied on args. That suggests that the args should be an array.

So, in your code the second parameter should be of an array type:

this._map.fitBounds(this._map, [this._bounds]);

You can also include the second element of the array that will be transformed into the second optional parameter padding of the Maps JavaScript API fitBound() method.

this._map.fitBounds(this._map, [this._bounds, 100]);

Hope this helps!

xomena
  • 31,125
  • 6
  • 88
  • 117
  • Thanks! but ```this._bounds``` is an object, so the spread operator should work without wrapping it in an array. I tried wrapping it just to test, but nothing happens, no error and the map won't fit the markers. – Dan H Jun 13 '17 at 20:54
  • If you spread the object you will have iterable properties of this object as parameters of map.fitBounds(). But the first parameter must be entire LatLngBounds or LatLngBoundsLiteral according to the [documentation](https://developers.google.com/maps/documentation/javascript/reference#Map). Can you try to put breakpoint at this function call and check this._bounds object? – xomena Jun 13 '17 at 21:08
  • Do you have this issue with initial render? The documentation says: "componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render." https://facebook.github.io/react/docs/react-component.html#componentdidupdate – xomena Jun 13 '17 at 21:17
0

This is how you call panTo and fitBounds with react map ref

this.map.panTo({
  lat:e.latLng.lat(), lng: e.latLng.lng()
})
const bounds = new google.maps.LatLngBounds()
bounds.extend({
  lat:e.latLng.lat(), lng: e.latLng.lng()
})
this.map.fitBounds(bounds)
fiddlest
  • 1,262
  • 2
  • 17
  • 42