google-maps-react icon indicating copy to clipboard operation
google-maps-react copied to clipboard

Marker click causes flicker

Open andrecalvo opened this issue 6 years ago • 11 comments

Hey,

Firstly, thanks for your work on this project!

I have noticed that when clicking markers (as seen on the demo) it causes all markers on the map to hide/show very quickly causing a flickering effect.

I was wondering if there is a way to stop this? I imagine it's because clicking the markers triggers a re-render?

Cheers

andrecalvo avatar Oct 11 '19 15:10 andrecalvo

@andrecalvo did you solve this issue?

oleksii-boiko avatar Nov 01 '19 18:11 oleksii-boiko

Hi @andrecalvo and @oleksii-boiko, have a look at your network tab when the flickering occurs. It's likely that the images are being re-rendered on each state change. The issue may potentially be solved by memoization. Read into how to memoize your state calls/functions to optimize their renders.

Hopefully that helps!

JacksonMalloy avatar Feb 24 '20 23:02 JacksonMalloy

This was driving me crazy! When I was almost giving up...somehow it worked and stopped flickering! It was flickering even after the user dragged the map a couple pixels to any direction.

It stopped flickering when I replaced my key in the marker from an integer to a string! Not sure that was the root cause for that...but for instance, markers with integer values for labels will not show the label...maybe there is a relation!

My key went from

<Marker key={id} ... />

to

const key = "" + id;
...
<Marker key={key} ... />

Go figure!

felipenmoura avatar Nov 18 '20 04:11 felipenmoura

Reopening this issue.

@JacksonMalloy how would we be able to Memoize the markers? Since we cannot wrap the Marker component with our own components this is going to be quite hard.

kevinvugts avatar Jan 11 '21 16:01 kevinvugts

Reopening this issue.

@JacksonMalloy how would we be able to Memoize the markers? Since we cannot wrap the Marker component with our own components this is going to be quite hard.

I'm facing the same issue. I want to wrap marker with a react.memo but I can`t :(

dsantoro avatar Jan 15 '21 14:01 dsantoro

This was driving me crazy! When I was almost giving up...somehow it worked and stopped flickering! It was flickering even after the user dragged the map a couple pixels to any direction.

It stopped flickering when I replaced my key in the marker from an integer to a string! Not sure that was the root cause for that...but for instance, markers with integer values for labels will not show the label...maybe there is a relation!

My key went from

<Marker key={id} ... />

to

const key = "" + id;
...
<Marker key={key} ... />

Go figure!

Hey @felipenmoura nice to see you here haha. I tried your solution but did not work for me. Im my case I'm trying to highlight a Marker when the user mouse is over a list. I capture the onMouseOver event and send it to my redux. In the map I check if redux value corresponds to marker id and change the icon to highlight it. But every time I hover my list all the pins are re-rendered and causes the flicker :(

dsantoro avatar Jan 15 '21 14:01 dsantoro

I had this issue for a long time. Recently I dug into this a little more and looked at how the library is rendering the markers. Found this code in Marker.js

 value: function componentDidUpdate(prevProps) {
        if (this.props.map !== prevProps.map || this.props.position !== prevProps.position || this.props.icon !== prevProps.icon) {
          if (this.marker) {
            this.marker.setMap(null);
          }
          this.renderMarker();
        }
      }

In my case I was passing in an object for icon and an object for position. Every time my map component would rerender, it would pass in a new object (even though the object has same values inside). Since the library does shallow compare it thinks the values have changed so it rerenders the marker.

I fixed this by keeping a reference to the position / icon objects, so even if a rerender occurs on my map, it grabs the same position/icon obects.

case12 avatar Sep 17 '21 14:09 case12

I have a similar issue. Using the base sample for a Map component, the Marker will flicker when moving the map.
I noticed I only have this issue if I use Next version 12 with React version 18. Using exactly the same map component, but changing out the version numbers for both Next and React to 11 and 17 respectively, the issue disappears.

CodeSandbox with Next 12 and React 18: https://codesandbox.io/s/condescending-dhawan-ylwll4?file=/pages/Map.js CodeSandbox with Next 11 and React 17: https://codesandbox.io/s/confident-wind-z67gi8?file=/pages/Map.js

For me it seems to be related to React 18

asdutoit avatar Jun 24 '22 12:06 asdutoit

I had this issue for a long time. Recently I dug into this a little more and looked at how the library is rendering the markers. Found this code in Marker.js

 value: function componentDidUpdate(prevProps) {
        if (this.props.map !== prevProps.map || this.props.position !== prevProps.position || this.props.icon !== prevProps.icon) {
          if (this.marker) {
            this.marker.setMap(null);
          }
          this.renderMarker();
        }
      }

In my case I was passing in an object for icon and an object for position. Every time my map component would rerender, it would pass in a new object (even though the object has same values inside). Since the library does shallow compare it thinks the values have changed so it rerenders the marker.

I fixed this by keeping a reference to the position / icon objects, so even if a rerender occurs on my map, it grabs the same position/icon obects.

Hi, Could you please elaborate how did you solved this issue?

itsmejasbirsingh avatar Aug 10 '22 07:08 itsmejasbirsingh

I'm pretty sure it's not a good solution but it fix the flickering for me:

Just update the code in Marker file by adding a JSON.stringify to the position to avoid the error caused by new reference to the object with:

value: function componentDidUpdate(prevProps) {
        if (this.props.map !== prevProps.map || JSON.stringify(this.props.position) !== JSON.stringify(prevProps.position) || this.props.icon !== prevProps.icon) {
          if (this.marker) {
            this.marker.setMap(null);
          }
          this.renderMarker();
        }
      }

Makeit-Tipi avatar Oct 28 '22 09:10 Makeit-Tipi

Just update the code in Marker file by adding a JSON.stringify to the position to avoid the error caused by new reference to the object.

I had to JSON.stringify also the icon prop. After that the flickering was gone :)

value: function componentDidUpdate(prevProps) {
        if (this.props.map !== prevProps.map || JSON.stringify(this.props.position) !== JSON.stringify(prevProps.position) || JSON.stringify(this.props.icon) !== JSON.stringify(prevProps.icon)) {
          if (this.marker) {
            this.marker.setMap(null);
          }
          this.renderMarker();
        }
      }

timossian avatar Oct 25 '23 06:10 timossian