1

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; ```
4
  • 1
    Please remove your API key from the code and change this in the Google API console, otherwise it will be used by others. Commented Jun 6, 2021 at 23:47
  • Omg thank you for catching that! Commented Jun 6, 2021 at 23:48
  • You're welcome. I've done things like that before too. Don't forget to change it in the console. Sites like these are likely scraped for API keys like that. Commented Jun 6, 2021 at 23:50
  • @WillWalsh The key is still visible in the history of your post (which is publicly available). In case you don't use that key anymore, no need to bother. Commented Mar 16, 2023 at 10:07

2 Answers 2

2

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'));
Sign up to request clarification or add additional context in comments.

1 Comment

This indeed in the answer and it works. Verified :)
1

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;

1 Comment

Thank you! This was the only thing that worked for me.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.