Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updating center from parent does not reposition map #546

Closed
jseparovic opened this issue Mar 21, 2018 · 14 comments
Closed

updating center from parent does not reposition map #546

jseparovic opened this issue Mar 21, 2018 · 14 comments
Assignees

Comments

@jseparovic
Copy link

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>
        );
    }
}
@itsmichaeldiego
Copy link
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.

@itsmichaeldiego
Copy link
Member

@jseparovic
Copy link
Author

jseparovic commented Mar 22, 2018

@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 }
                    />

@jseparovic
Copy link
Author

jseparovic commented Mar 22, 2018

@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

@itsmichaeldiego
Copy link
Member

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

@jseparovic
Copy link
Author

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

@jseparovic
Copy link
Author

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

@jseparovic
Copy link
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

@itsmichaeldiego
Copy link
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!

@itsmichaeldiego itsmichaeldiego self-assigned this Mar 23, 2018
@itsmichaeldiego itsmichaeldiego added bug and removed bug labels Mar 23, 2018
@itsmichaeldiego
Copy link
Member

itsmichaeldiego commented Mar 23, 2018

@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.

@jseparovic
Copy link
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

@itsmichaeldiego
Copy link
Member

Great @jseparovic, I am glad I was helpful!

@samrjenkins
Copy link

@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)

@undeletable
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants