11

Hi folks I'm using the react-google-maps library. I'm trying to recenter my map (zoom where the marker is) every time my location changes, but I'm getting a bit lost on how to implement the whole thing. I can see the marker being updated, but the map stays on its defaultCenter position.

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  GoogleMap,
  Marker,
  withScriptjs,
  withGoogleMap
} from 'react-google-maps';

import environment from '../../config/environment';

class Map extends Component {
  static propTypes = {
    defaultZoom: PropTypes.number,
    center: PropTypes.shape({
      lat: PropTypes.number,
      lng: PropTypes.number
    }),
    location: PropTypes.shape({
      lat: PropTypes.number,
      lng: PropTypes.number
    }),
    onPositionChanged: PropTypes.func
  };

  static defaultProps = {
    defaultZoom: 14,
    center: {
      lat: 60.1699,
      lng: 24.9384
    },
    location: {},
    onPositionChanged: () => {}
  };

  constructor(props) {
    super(props);
    this.mapRef = React.createRef((ref) => {
      this.mapRef = ref;
    });
  }

  componenDidUpdate() {
    console.log(`I'm about to update with props: ${JSON.strongify(prevProps, undefined, 2)}`);
  }

  onPositionChanged = (location) => {
    console.log(`This the new location onPositionChange:${JSON.stringify(location, undefined, 2)}`);
    const newLocation = new window.google.maps.LatLng(location.lat, location.lng);
    // [NOTE]: try using the panTo() from googleMaps to recenter the map ? but don't know how to call it.

    return (
      <Marker
        position={newLocation}
      />
    );
  }

  render() {
    const {
      center,
      defaultZoom,
      location,
      onPositionChanged
    } = this.props;

    return (

      <GoogleMap
        className="google-map"
        onClick={onPositionChanged(location)}
        defaultZoom={defaultZoom}
        defaultCenter={center}
        ref={this.mapRef}
      >

        {/* <Marker
          position={location}
        /> */}

        { this.onPositionChanged(location) }
      </GoogleMap>
    );
  }
}

const SchedulerGoogleMap = withScriptjs(withGoogleMap(Map));
const SchedulerMap = props => (
  <SchedulerGoogleMap
    googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${
      environment.GOOGLE_MAPS_API_KEY
    }&v=3`}
    loadingElement={<div style={{ height: '20vh' }} />}
    containerElement={<div style={{ height: '100%' }} />}
    mapElement={<div style={{ height: '20vh', width: '100%' }} />}
    {...props}
  />
);


export { Map, SchedulerMap, SchedulerGoogleMap };
Zoe
  • 27,060
  • 21
  • 118
  • 148
intercoder
  • 2,171
  • 7
  • 23
  • 34

3 Answers3

22

Simply pass the center prop to your GoogleMap component instead of the defaultCenter prop. The center prop is mutable whereas defaultZoom is not.

Patrick Connors
  • 5,677
  • 6
  • 27
  • 54
3

This is what it seemed to work for me, just in case any other person runs into the same problem.

... ommited_code

class Map extends Component {

... ommited_code

  componentDidUpdate(prevProps) {
    if (prevProps.location !== this.props.location) {
      this.mapRef.panTo(
        new window.google.maps.LatLng(this.props.location.lat, this.props.location.lng)
      );
    }
  }

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

    return (

      <GoogleMap
        className="google-map"
        defaultZoom={defaultZoom}
        defaultCenter={center}
        ref={(ref) => {
          this.mapRef = ref;
        }}
      >
        <Marker position={new window.google.maps.LatLng(location.lat, location.lng)} />
      </GoogleMap>
    );
  }
}

...ommited_code
intercoder
  • 2,171
  • 7
  • 23
  • 34
0

panTo() is a method of the google.maps.Map class. (https://developers.google.com/maps/documentation/javascript/reference/map#Map.panTo)

It seems to be the function you are looking for, so you need to call it on your google map by referencing the className you set for your map, then give the panTo method the LatLang object you created:

window.google.maps.Map(document.getElementsByClassName("google-map")).panTo(newLocation);

Hayden E
  • 108
  • 8
  • just tried it, but it gives me a `cannot find defaultView` error when I try to set it on `onPositionChanged` method – intercoder Sep 11 '18 at 10:20