Search code examples
reactjszoomingreact-google-maps

React-google-maps zoom issue


I'm using react.google.maps and I'm trying to display different markers based on zoom level. The problem I have is that sometimes when I zoom, the map is not updated (the map tiles are not re-rendered based on the zoom level). This happens when I have the onZoomChanged method defined. If I remove it, everything works ok.

This is how my class looks like:

class Map extends Component {
  constructor(props) {
    super(props);

    this.googleMap = React.createRef();

    this.state = {
      zoom: 2
    };
  }

  onZoomChanged = () => {
    this.setState({
      zoom: this.googleMap.current.getZoom()
    });
  };

  getMarkers() {
    const { zoom } = this.state;
    let Markers = null;

    // get markers based on zoom

    return Markers;
  }

  render() {
    const { center } = this.props;

    return (
      <GoogleMap
        defaultZoom={2}
        defaultCenter={{
          lat: center.latitude,
          lng: center.longitude
        }}
        defaultOptions={{
          mapTypeControl: false,
          streetViewControl: false,
          zoomControl: false,
          fullscreenControl: false,
          styles: mapStyles,
          minZoom: 2,
          maxZoom: 10
        }}
        ref={this.googleMap}
        onZoomChanged={this.onZoomChanged}
      >
        {this.getMarkers()}
      </GoogleMap>
    );
  }
}

Here are some screenshots to illustrate the behavior:

Actual 1

Expected 1

Actual 2

Expected 2

Any help would be appreciated. Thanks in advance!


Solution

  • Ok...it seems that my issue was related to the center or at least this fixed it:

    onZoomChanged = () => {
      const newCenter = this.googleMap.current.getCenter();
      this.setState({
        zoom: this.googleMap.current.getZoom(),
        center: {
          latitude: newCenter.lat(),
          longitude: newCenter.lng()
        }
      });
    };
    

    I also changed the center on onIdle method:

    onIdle = () => {
      const { center } = this.state;
      const newCenter = this.googleMap.current.getCenter();
      const centerLng = newCenter.lng();
      const centerLat = newCenter.lat();
    
      // other logic for bounds
    
      if (center.latitude !== centerLat || center.longitude !== centerLng) {
        this.setState({
          center: {
            latitude: centerLat,
            longitude: centerLng
          }
        });
      }
    };