Skip to content

updating center from parent does not reposition map #546

Description

@asyncjason

sorry, I've searched and can't seem to find the answer.

I'm updating center of map from parent component but the map is not repositioning. What am I missing here?
Cheers

export class GMapReact extends Component {
    render() {
        console.log("center:", this.props.center);
        return (
            <GoogleMap
                bootstrapURLKeys={{ key: [GOOGLE_API_KEY] }}
                center={this.props.center}
                zoom={this.props.zoom}
            >
                {this.props.markers.map((marker, i) => {
                    return (
                        <MarkerComponent
                            key={i}
                            lat={marker.latitude}
                            lng={marker.longitude}
                            text={marker.name}
                        />
                    )
                })}
            </GoogleMap>
        );
    }
}

Activity

  1. itsmichaeldiego commented on Mar 21, 2018

    @itsmichaeldiego
    Member

    @jseparovic Do you interact with the map before you change the center? If that is the case, this might be related to #176 and your solution would be using _onChange method, you can see an example in here: https://jsbin.com/roqutisoqu/1/edit?js,console,output

    If you're not interacting with the map, and you trying to change the center, I need to know what is the method you're using to change the center. Please provide a live example if possible.

  2. itsmichaeldiego commented on Mar 21, 2018

    @itsmichaeldiego
    Member
  3. asyncjason commented on Mar 22, 2018

    @asyncjason
    Author

    @itsmichaeldiego I'm just using the parent state and updating it when a user finds a google place in a search field (using react-places-autocomplete)

    The handler method looks like:

        handlePlaceSelect = (place) => {
            this.updateState(STATE_SECTION_INPUTS, {place: place});
            this.updateState(STATE_SECTION_MAP, {lat: this.getPlaceLatitude()});
            this.updateState(STATE_SECTION_MAP, {lng: this.getPlaceLongitude()});
        };
    

    updateState function is just a setState wrapper:

        updateState(section, stateChange) {
            var state = Object.assign({}, this.state);
            for(var key of Object.keys(stateChange))
            {
                console.log("updating", key, stateChange[key]);
                state[section][key] = stateChange[key];
            }
            this.setState(state);
        }
    

    And the component in the parent render()

                        <GMapReact
                            center={ this.state.map }
                            zoom={ 15 }
                            markers={ this.state.results.items }
                        />
    
  4. asyncjason commented on Mar 22, 2018

    @asyncjason
    Author

    @itsmichaeldiego I've tried to setup a demo
    I'm using react 16.2.0 in my project btw

    For some reason the map doesn't show in the demo

    I'm trying to simulate the update in parent state to show the map not recentering, but not having much luck

    https://codesandbox.io/s/5z35k7566x

  5. itsmichaeldiego commented on Mar 22, 2018

    @itsmichaeldiego
    Member

    @jseparovic Have you tried this? #512 (comment)

  6. asyncjason commented on Mar 22, 2018

    @asyncjason
    Author

    @itsmichaeldiego I did try that, but I thought that was more for resizing the browser window?

  7. asyncjason commented on Mar 23, 2018

    @asyncjason
    Author

    @itsmichaeldiego is it possibly a v16 issue? That's what I'm using in my project, and same in the codesandbox

  8. asyncjason commented on Mar 23, 2018

    @asyncjason
    Author

    @itsmichaeldiego I have the codesandbox showing the issue now. center is updated, but the map does not recenter:

    https://codesandbox.io/s/mjp08rvxmj

    This is also using v16.2.0

  9. itsmichaeldiego commented on Mar 23, 2018

    @itsmichaeldiego
    Member

    @jseparovic You're right, I can reproduce it, let me work on an example on my own to see how can we make this work!

  10. itsmichaeldiego commented on Mar 23, 2018

    @itsmichaeldiego
    Member

    @jseparovic Hey, I think the problem is related on how the state works. Check this repo I created a while ago for an interview, here I change the center: https://github.com/itsmichaeldiego/earthquaker.
    Feel free to clone the project, run yarn and then yarn start and it will work, I just tested, it works like a charm. I also just updated google-map-react to 0.34.0.

  11. asyncjason commented on Mar 23, 2018

    @asyncjason
    Author

    @itsmichaeldiego you're right, it was my updateState setState wrapper. For some reason I thought I had to update this way to maintain other state keys, but I see setState already does this.
    Thanks for you help. Cheers

    working here: https://codesandbox.io/s/2oy1nj9kyy

  12. itsmichaeldiego commented on Mar 23, 2018

    @itsmichaeldiego
    Member

    Great @jseparovic, I am glad I was helpful!

  13. samrjenkins commented on Mar 4, 2022

    @samrjenkins

    @itsmichaeldiego interestingly I encountered this problem again using v1.1.7. After a couple of hours of trying every solution listed in the repo issues, downgrading from v1.1.7 to v0.34.0 fixed the issue. Upgrading to v2.0.4 also brings the issue back again!

    This can be seen by trying the different package versions on @jseparovic's sandbox: #546 (comment)

  14. undeletable commented on Mar 26, 2022

    @undeletable

    I've encountered a similar issue. Assume the following code:

    import React, {Fragment, useEffect, useState} from 'react';
    import GoogleMapReact from 'google-map-react';
    
    const Map = () => {
      const [center, setCenter] = useState();
    
      useEffect(() => {
        window.navigator.geolocation.getCurrentPosition(position => {
          setCenter({
            lat: position.coords.latitude,
            lng: position.coords.longitude
          });
        });
      }, []);
    
      return <Fragment>
        <GoogleMapReact
          bootstrapURLKeys={{ key: 'my_api_key' }}
          center={center}
          yesIWantToUseGoogleMapApiInternals
        />
      <button
        onClick={() => window.navigator.geolocation.getCurrentPosition(position => {
          setCenter({
            lat: position.coords.latitude,
            lng: position.coords.longitude
          });
        })}
      >
        Locate Me
      </button>
      </Fragment>;
    };
    

    Execute the following steps:

    1. Click 'Locate Me' button - map would be centered to the detected location.
    2. Move the map.
    3. Click 'Locate Me' - map would not be centered, even thougn center prop receives the expected value.

    This might seem weird, but in fact that's not surprising. On the following scenario center prop value is not changed (on steps 1 and 3 coordinates are the same). One might note that since center is of object type, its reference is changed and it should result in component's rerender anyway, but look at component source code. Current and previous center values are being compared, and map is re-centered only if they are different enough. Thus, we can get things working for the above-mentioned scenario by adding the following prop to GoogleMapReact: onChange={e => setCenter(e.center)} (this function would be triggered on each map move).

    Such a behavior of component might be confusing. IMHO, when deciding whether to re-center map programmatically, it makes sense to compare center value with current actual center (created PR for that: #1100). But if this is expected, it would be helpful to add note about that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions