google-maps-react
google-maps-react copied to clipboard
Clicking on infowindow and then back to map rerenders markers.
Why are markers rerendered everytime there is some interaction with infowindow?
this project does not use react very well. the authors wrote this so they could market their book. ironically marketed by saying "learn react the right way"
https://reactjs.org/docs/react-component.html#shouldcomponentupdate
Use shouldComponentUpdate() to let React know if a component’s output is not affected by the current change in state or props. The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior.
@Qwiso do you know any other library which doesn't requires too much setup... I did tried using should ComponentUpdate but too much of if statements and still for one case I am unable to handle the update.... This updating thing should be part of core module only then it will work in all scenarios. Would be great if you can tell me any other library.
even if I update other state variables on the screen/component which are not used for map component also rerendering the map component. This should not be expected behaviour does anyone know how to fix it ?
@kashifaliquazi yup it is happening. Mayb to keep mapview away from redux? Thats the only way i think to avoid rerendering
To solve this issue of re-rendering and to allow for editing of SVG data which is mentioned in other issues, I implemented a new property in Marker.js
and changed the logic of the componentDidUpdate
method
{
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
if (this.props.shouldRender) {
this.marker.setMap(null)
this.renderMarker()
}
}
}
in the render method of my map view, I create each marker based on custom object I am using from the state
let userMarkers = this.state.userMarkers.map((marker, index) => {
let userMarker = <Marker
key={index}
name={marker.name}
position={marker.position}
icon={marker.iconSVG}
onClick={this.onMarkerClick}
shouldRender={marker.shouldRender}
/>
marker.shouldRender = false
return userMarker
})
and finally,
<Map
styles={this.state.mapStyle}
onClick={this.onMapClicked}
google={this.props.google}
zoom={10}
center={this.state.panToPos ? this.state.panToPos : null}
>
{userMarkers}
</Map>
@Qwiso
{
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
if (this.props.shouldRender) {
this.marker.setMap(null)
this.renderMarker()
}
}
}
Is this ES5?
@themakerman it's just the part of the source code that i've changed. Marker.js
from google-maps-react module. that what it looks like. not sure if it's ES5
@Qwiso Ohh i got it. You edited the module itself. Why not PR?
@themakerman because, as written, it's a breaking change to the existing functionality. it's not a great way of doing things but it works for me
Extending the Marker component works in the meantime until the comparison fix is merged:
class CustomMarker extends Marker {
componentDidUpdate(prevProps) {
if(
this.props.map !== prevProps.map ||
this.props.icon.url !== prevProps.icon.url ||
(
this.props.position.lat !== prevProps.position.lat ||
this.props.position.lng !== prevProps.position.lng
)
) {
if(this.marker) {
this.marker.setMap(null);
}
this.renderMarker();
}
}
}
@srobertson421 , Your solution is pretty nice, but still forces me to pass property icon
otherwise I will get error, so I do a little patch hope it helps:
class CustomMarker extends Marker {
componentDidUpdate(prevProps) {
if(
this.props.map !== prevProps.map ||
(this.props.icon && ( this.props.icon.url !== prevProps.icon.url )) ||
(
this.props.position.lat !== prevProps.position.lat ||
this.props.position.lng !== prevProps.position.lng
)
) {
if(this.marker) {
this.marker.setMap(null);
}
this.renderMarker();
}
}
}
When I use custom url for marker, it re renders the marker. Is there any solution to fix that ?
@radinreth and @srobertson421 - sending many many blessings to your and your family and your cousin and friends. I couldn't knock it and your code works beautifully.
Extending the Marker component works in the meantime until the comparison fix is merged:
class CustomMarker extends Marker { componentDidUpdate(prevProps) { if( this.props.map !== prevProps.map || this.props.icon.url !== prevProps.icon.url || ( this.props.position.lat !== prevProps.position.lat || this.props.position.lng !== prevProps.position.lng ) ) { if(this.marker) { this.marker.setMap(null); } this.renderMarker(); } } }
What is the status of this? Is it already integrated into the lib?
@kevinvugts currently this is still the only workaround. This library isn't very well supported.