Back to overview

Easy way to integrate Google Maps in React

Laptop displaying Google Maps
| 4 min read
View count:

More often than not, you will be asked to add a map coming from Google Maps to websites you are developing. This might seem like a pain to integrate in your React application, but luckily Alexey Lyakhov created a package to make it all a bit easier: React Google Maps API. It’s well documented too!

Now, let’s dive into the actual code to create a component using this package!

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

type OfficeNode = {
  id: string,
  field_address: {
    locality: string,
    postal_code: string,
    address_line1: string,
    address_line2: string,
    latitude: number,
    longitude: number,
  },
};

export default function App() {
  const offices = [
    {
      id: '1',
      field_address: {
        locality: 'Gent',
        postal_code: '9000',
        address_line1: 'Veldstraat 1',
        address_line2: 'a',
        latitude: 51.053589,
        longitude: 3.72242,
      },
    },
    {
      id: '2',
      field_address: {
        locality: 'Brussel',
        postal_code: '1000',
        address_line1: 'Nieuwstraat 1',
        address_line2: 'a',
        latitude: 50.85061,
        longitude: 4.35403,
      },
    },
    {
      id: '3',
      field_address: {
        locality: 'Antwerpen',
        postal_code: '2000',
        address_line1: 'Meir 1',
        address_line2: 'a',
        latitude: 51.21878,
        longitude: 4.40559,
      },
    },
  ];
  const mapRef = React.useRef < any > null;
  const [selectedOffice, setSelectedOffice] =
    (React.useState < OfficeNode) | undefined | (null > null);
  const { isLoaded } = useJsApiLoader({
    id: 'google-map-script',
    googleMapsApiKey: 'ENTER-YOUR-API-KEY-HERE',
  });
  const onLoad = React.useCallback(
    mapInstance => {
      const bounds = new google.maps.LatLngBounds();
      offices.forEach(office => {
        bounds.extend(
          new google.maps.LatLng(
            office.field_address.latitude,
            office.field_address.longitude
          )
        );
      });
      mapRef.current = mapInstance;
      mapInstance.fitBounds(bounds);
    },
    [offices]
  );
  const onClickMarker = (officeId: string) => {
    setSelectedOffice(offices.find(office => office.id === officeId));
  };
  return (
    <div className="App">
      <h1 class="mb-4 text-3xl">Google maps + React</h1>
      {isLoaded ? (
        <>
          <GoogleMap
            mapContainerClassName="c-office-overview__map"
            onLoad={onLoad}
          >
            {offices.map(office => (
              <Marker
                key={office.id}
                onClick={() => onClickMarker(office.id)}
                position={{
                  lat: office.field_address.latitude,
                  lng: office.field_address.longitude,
                }}
              />
            ))}
            {selectedOffice ? (
              <InfoWindow
                position={{
                  lat: selectedOffice.field_address.latitude,
                  lng: selectedOffice.field_address.longitude,
                }}
                onCloseClick={() => setSelectedOffice(null)}
              >
                <p>
                  {selectedOffice.field_address.address_line1}{' '}
                  {selectedOffice.field_address.address_line2} -{' '}
                  {selectedOffice.field_address.postal_code}{' '}
                  {selectedOffice.field_address.locality}
                </p>
              </InfoWindow>
            ) : null}
          </GoogleMap>
        </>
      ) : null}
    </div>
  );
}

So let’s see what’s going on here. We import the different needed components from the library and we select the needed library (only places needed for this demo). After this is done, we can create a Ref with the useRef hook, this will be used to store the reference to the Google Maps map.

We then use the useJsApiLoader hook to initialise the Google Maps API, passing the API key. From the response of this hook, we can get the isLoaded boolean back, this will be used to show/hide the map in our rendering. We also need to create an onLoad function (wrapped in a useCallback hook), this will be called by the Google Maps API once it’s done initialising. In this function we’ll loop over our offices, and add positions to the bounds of our Google Map, so the map is correctly centered, and we’ll assign the Google Maps instance to our Ref we created earlier.

In our rendering, it’s all pretty straightforward. We render our map once the isLoaded boolean is true. We render a marker for every office, and add an onClick listener to select the office when the marker is clicked.

We also have a check in the code to see if selectedOffice, when an office is selected we want to use the InfoWindow from Google Maps to show some details of the office. When the close button is clicked, the selectedOffice will be cleared.

And that’s it! I hope this was helpful. I might write a follow-up article where I explain how to search for addresses with Google Maps Places, and how to search the closest office to the address. This would also include working with the built-in geolocation API in the browsers. If you’d be interested in this, leave a comment :-)

Source code can be found on Codesandbox (you still need to enter a Google Maps API key, I can’t give out mine since I’d get charged :D)

Did you like this post? Check out my latest blog posts:

Astral picture
29 Mar 2024

Astro DB: Migrating my analytics data from Vercel Postgres

5 min reading time

  • astro
  • database
  • vercel
  • postgres
  • libsql
Screenshot of an analytics dashboard
16 Jan 2024

Basic analytics with Vercel Postgres - Drizzle - Astro

10 min reading time

  • vercel
  • databases
  • typescript
  • astro
Page of a dictionary
15 Nov 2023

A minimal dependency-free translation system for Next.js

6 min reading time

  • nextjs
  • react
  • javascript