react-google-maps / api Evitando renderizar novamente o mapa após algumas mudanças de estado

Nov 08 2020

Eu estava tendo problemas onde minha instância do GoogleMaps se atualizava e se autocentrava em alguma onClickfunção onde o estado estava sendo definido e todo o ciclo de renderização do componente acontecia.

Após algumas pesquisas no Google, foi sugerido que a instanciação do componente fosse separada e reutilizada. O problema agora é que tenho alguma lógica para exibir marcadores dentro do <GoogleMaps>componente que não está mais funcionando como esperado e não sei como refatorar:

export default function LocationSearchResults({
    ...
    }) {
    const [map, setMap] = useState(null)
    const [markersContainer, setMarkersContainer] = useState([])

    const getMap = () => {

        if (map) {
            return map;
        } else {
            setMap(<GoogleMap mapContainerStyle={containerStyle}
                options={ {
                        minZoom: 3,
                        maxZoom: 15
                    }}
                center={{
                        lat: 49.25,
                        lng: -84.5
                    }}
                zoom={5}
                onLoad={onLoad}
                onDragEnd={onDragEnd} >
                {
                    markersContainer.map(place => { //Only executes once? Does not listen for changes
                        return (< Marker key={place.id}
                            position={ place.position}
                        />
                        )
                    })

                }

                </GoogleMap>

                )

                return map

            }
        }

        render( <div className="..." >
                    {
                     getMap()
                    } 
            </div>
        )
    }

Não tenho muita experiência com React, qualquer ajuda é apreciada, obrigado!

Respostas

smooth_smoothie Nov 09 2020 at 01:19

Eu configurei minha instanciação de componente usando useMemo

...instantiate all event listener functions here

const map = useMemo(() =>
 {
   return (<GoogleMap
    mapContainerStyle={containerStyle}
    options={{ minZoom: 3, maxZoom: 15 }}
    center={{
      lat: 49.25,
      lng: -84.5
    }
    }
    zoom={5}
    onLoad={onLoad}
    onDragEnd={onDragEnd}
  // onUnmount={onUnmount}
  >
     {markersContainer.map(place => { return ( <Marker
                    key={place.id}
                    position={place.position} />
                    )
                   })
    }
 </GoogleMap>)

}, [markersContainer])

então eu simplesmente renderizo em minha função render ():

return (
    <>
<div>...
  {map}
</div>
</>)

Não há mais atualizações desnecessárias, a menos que novos marcadores sejam adicionados / removidos.