Clickable markers in a google-maps-react component

Kirsten Werner
Kirsten Werner
Published in
3 min readNov 15, 2019

So you’ve got a nifty Google Map imbedded in your React app (or if you don’t yet, go ahead and check out my blog on how to get that up and running — Integrating Google Maps into your React app). That’s super cool. But wouldn’t it be even cooler if your users could click on the markers that show up, and get some more detailed information about whatever the marker is marking?

The google-maps-react package that you installed to render the map in your app has a simple way to solve this! If you’ll remember, we have a Map component in our app that so far looks like this:

import React from "react";
import { withScriptjs, withGoogleMap, GoogleMap, Marker, InfoWindow } from "react-google-maps";
const Map = withScriptjs(withGoogleMap((props) =>{
const recycleCenters = props.recycleCenters

return (
<GoogleMap zoom={4.5} center={ { lat: 39.6693, lng: -98.3476 } } />

{recycleCenters.map(center => (
<Marker
key={center.id}
position={{
lat: center.latitude,
lng: center.longitude
}}
/>
))};
</GoogleMap>}))export default Map;

First, notice that with the import from react-google-maps, we’ve included something called Infowindow. The Info window is exactly what we want to pop up when we click on a marker.

So what do we want to show in the info window? You can put anything you want in here! You can add pictures (think Redfin, when you click on a marker for a house for sale, and it pops up a picture of the house!), or any other information about the location that you have saved into your props that are being passed into the Map component.

In order for our app to know what marker has been clicked on, we’ll need to set the state like so —

const [selectedCenter, setSelectedCenter] = useState(null);

Then we, of course, need to add an event listener to our marker —

<Marker
key={center.id}
position={{
lat: center.latitude,
lng: center.longitude
}}
onClick={() => {
setSelectedCenter(center);
}}
/>

But we need to make sure that the info window shows up right on top of the marker, where we want it to. To do this, lets create the Infowindow that we imported from our react-google-maps package, and set the latitude and longitude

{selectedCenter && (
<InfoWindow
onCloseClick={() => {
setSelectedCenter(null);
}}
position={{
lat: selectedCenter.latitude,
lng: selectedCenter.longitude
}}
>
</InfoWindow>
)}

So good so far, now we have an empty window that pops up when we click on a marker! Filling in the info window with whatever you want is easy. For my RecycleIt! app, I wanted users to be able to see the name, address, phone number, and hours of operation for their selected center, and having passed that information to my Map component as props, I can format it like so —

<div>
<h3>{selectedCenter.name}</h3>
<h5>{selectedCenter.address}, {selectedCenter.city},{selectedCenter.state} {selectedCenter.zip_code}</h5>
<h5>{selectedCenter.phone_number}</h5>
<p>Hours of operation: {selectedCenter.hours}</p>
</div>

Note that wrapping the display information in a <div/>, I am able to format with CSS — I could even add a className to the div, and set my CSS styling in my app.css file!

The last thing of importance when creating info windows that pop up when a user clicks on a marker, is that you don’t want that window to stay open forever. How annoying would it be if once you open one info window, it just stays….eventually your whole screen would be covered with overlapping info windows! React-google-maps gives us a handy method called useEffect that neatly handles this for us.

useEffect(() => {
const listener = e => {
if (e.key === "Escape") {
setSelectedCenter(null);
}
};
window.addEventListener("keydown", listener); return () => {
window.removeEventListener("keydown", listener);
};
},
[]);

And thats it! Now we have not only a working map, but one that displays markers for whatever locations our search returns, AND has info windows that open up when a user clicks on a marker!

You can check the official documentation for using info windows, including an example to see how to create a fully customized here:

Happy coding!

--

--

Kirsten Werner
Kirsten Werner

Junior Software Engineer searching for my place in the Tech World