Forrest Daggett
Forrest Daggett

Reputation: 21

react-google-maps resets map when using onClick events

I'm having difficulty implementing some simple react-google-maps code where whenever a marker is clicked or an info box is closed, the map will reset its position to the original position. I saw that I should be rendering the map component separately from changing the state, but I'm not sure how to implement this.

Any help is appreciated

import React, {useState} from 'react';
import {Marker, GoogleMap,LoadScript,InfoWindow} from '@react-google-maps/api';


const MapContainer = ({markers}) => {
    const [selected, setSelected] = useState<any>({})

    const onSelect = (item) => {
        setSelected(item)
    }

    const mapStyles = {
        height: "100vh",
        width: "100%",
    }

    const defaultCenter = {
        lat: 45.510440, lng: -122.683338
    }

    const renderMap = () => {
    return <>
        <div>
            <LoadScript
                googleMapsApiKey='[GOOGLE API KEY]'>
                <GoogleMap
                    mapContainerStyle={mapStyles}
                    zoom={13}
                    center={defaultCenter}
                    >

                {markers.map((marker)=> {
                    return(
                    <Marker 
                        position={{
                            lat: marker.lat,
                            lng: marker.lng
                        }}
                        title={marker.title}
                        onClick={ () => onSelect(marker) }
                    />
                )})
                }
                {
                    selected.lng &&
                    <InfoWindow
                    position={
                        {
                            lat: selected.lat,
                            lng: selected.lng
                        }
                    }
                    onCloseClick={() => setSelected({})}
                    >
                        <div>
                        <h3>{selected.title}</h3>
                        <p>{selected.info}</p>
                        </div>
                    </InfoWindow>
                }

                </GoogleMap>
            </LoadScript>
        </div>
    </>
    }

    return renderMap()
}

export default MapContainer; ```

Upvotes: 1

Views: 1777

Answers (2)

V&#237;tek Peterka
V&#237;tek Peterka

Reputation: 99

Put the center in a state and set it to null after tiles are loaded, like this:

import React, {useState} from 'react';
import {Marker, GoogleMap,LoadScript,InfoWindow} from '@react-google-maps/api';


const MapContainer = ({markers}) => {
    const [selected, setSelected] = useState<any>({})

    const onSelect = (item) => {
        setSelected(item)
    }

    const mapStyles = {
        height: "100vh",
        width: "100%",
    }

    const defaultCenter = {
        lat: 45.510440, lng: -122.683338
    }
    const [center, setCenter] = useState(defaultCenter)


    const renderMap = () => {
    return <>
        <div>
            <LoadScript
                googleMapsApiKey='[GOOGLE API KEY]'>
                <GoogleMap
                    mapContainerStyle={mapStyles}
                    zoom={13}
                    center={center}
                    onTilesLoaded={() => setCenter(null)}
                    >

                {markers.map((marker)=> {
                    return(
                    <Marker 
                        position={{
                            lat: marker.lat,
                            lng: marker.lng
                        }}
                        title={marker.title}
                        onClick={ () => onSelect(marker) }
                    />
                )})
                }
                {
                    selected.lng &&
                    <InfoWindow
                    position={
                        {
                            lat: selected.lat,
                            lng: selected.lng
                        }
                    }
                    onCloseClick={() => setSelected({})}
                    >
                        <div>
                        <h3>{selected.title}</h3>
                        <p>{selected.info}</p>
                        </div>
                    </InfoWindow>
                }

                </GoogleMap>
            </LoadScript>
        </div>
    </>
    }

    return renderMap()
}

export default MapContainer;

Upvotes: 1

Pagemag
Pagemag

Reputation: 2977

It seems that putting your center value in a state and setting the clicked marker coordinates as the new center will solve the issue. Here's a sample code and a code snippet:

import React, {useState} from 'react';
import {Marker, GoogleMap,LoadScript,InfoWindow} from '@react-google-maps/api';
import { render } from "react-dom";
import markers from "./data.json"
const MapContainer = () => {
    const [selected, setSelected] = useState<any>({})
    const [center,setCenter]= useState({
        lat: 39.952584, lng: -75.165221
    })

    const onSelect = (item) => {
        setSelected(item)
        setCenter({
        lat: item.lat, lng: item.lng
    })
    }

    const mapStyles = {
        height: "100vh",
        width: "100%",
    }


    const renderMap = () => {
    return <>
        <div>
            <LoadScript
                googleMapsApiKey='AIzaSyBlfuRgAUDPGJnUpwyyhdSBIs193bXboMQ'>
                <GoogleMap
                    mapContainerStyle={mapStyles}
                    zoom={13}
                    center={center}
                    >

                {markers.map((marker,i)=> {
                    return(
                    <Marker 
                    key={i}
                        position={{
                            lat: marker.lat,
                            lng: marker.lng
                        }}
                        title={marker.title}
                        onClick={ () => onSelect(marker) }
                    />
                )})
                }
                {
                    selected.lng &&
                    <InfoWindow
                    position={
                        {
                            lat: selected.lat,
                            lng: selected.lng
                        }
                    }
                    onCloseClick={() => setSelected({})}
                    >
                        <div>
                        <h3>{selected.id}</h3>
                        <p>{selected.name}</p>
                        </div>
                    </InfoWindow>
                }

                </GoogleMap>
            </LoadScript>
        </div>
    </>
    }

    return renderMap()
}


render(<MapContainer />, document.getElementById('root'));

Upvotes: 2

Related Questions