Currently, every components call instance.setOptions(googleMapsConfig) when componentDidUpdate method is fired, whether googleMapsConfig is changed or not. This will result in an unexpected behaviour.
Did you mean <GoogleMaps> component or <Marker> or both?
Would you like to be more elaborate on what _unexpected behaviour_ would like?
In my case, it's<GoogleMap>. For example, I have a component of the following class:
class MapCanvas extends React.Component {
render() {
return (
<GoogleMaps containerProps={{
style: {
height: '100%'
}
}}
googleMapsApi={google.maps}
ref="map"
zoom={6}
center={{lat: 42, lng: 42}}>
<InfoWindow content={`count: ${this.props.count}`} position={{lat: 44, lng: 44}}></InfoWindow>
</GoogleMaps>
);
}
}
MapCanvas.defaultProps = {
count: 1
};
The count in the prop will be updated every second. Accordingly, the setOptions method of the map instance will be invoked every second, so the map will pan to the default center {lat:42, lng:42} and zoom to 6 every second, regardless of that the map has been scrolled to other place by an user.
I know there are some workarounds. However, this is what I said "unexpected behaviour".
Maybe <GoogleMap> should call the setOptions method in the background only when an instance is created, like we usually do with native Google Maps api const map = new google.maps.Map(DOMNode, mapOptions). After that, we should control a map by calling setOption or other methods explicitly instead of changing props.
Or, maybe, we can let options be an immutable object prop of a <GoogleMap>, then check whether it has been changed in the shouldComponentUpdate internally.
Well, as I design the API, one thing I'd like to address is data-driven programming. So as a result, the input of a component (props) should ALWAYS reflect its current drawings. We can just change the UI by giving it new props and it will update accordingly. It's Reactive way of doing UI and that's why React.js is awesome.
For your question here, a solution is to treat <GoogleMaps> a stateful component (as it really is), and then when it's state changes, we can be notified by the event callback. Thus, you could set:
<GoogleMaps
{...initialProps}
onCenterChanged={this.updateCenter} center={this.state.center}
onZoomChanged={this.updateZoom} zoom={this.state.zoom}
/>
By doing this, your state is kept in sync with <GoogleMaps> internal state. This example shows exactly the same thing:
https://tomchentw.github.io/react-google-maps/#events/event-properties
I got your point and I believe you are right! We should never expose set methods outside the box. Thanks for your explanation. I will check it later to see whether we could call setOption as frequently as centerChanged events are triggered without losing performance significantly, and then I will close this issue.
It turns out that Google Map runs smoothly.
Cool man! Glad it works. Feel free to reopen the issue in the future.
Most helpful comment
Well, as I design the API, one thing I'd like to address is data-driven programming. So as a result, the input of a component (props) should ALWAYS reflect its current drawings. We can just change the UI by giving it new props and it will update accordingly. It's Reactive way of doing UI and that's why React.js is awesome.
For your question here, a solution is to treat
<GoogleMaps>a stateful component (as it really is), and then when it's state changes, we can be notified by the event callback. Thus, you could set:By doing this, your state is kept in sync with
<GoogleMaps>internal state. This example shows exactly the same thing:https://tomchentw.github.io/react-google-maps/#events/event-properties