DEV Community

loading...

How to Integrate the Google Maps API with React.js

talorlanczyk profile image TalOrlanczyk Updated on ・4 min read

In my journey to find how to integrate Google Maps with ReactJS, I stumble a lot of articles recommended to use the npm google-maps-react.

GitHub logo fullstackreact / google-maps-react

Companion code to the "How to Write a Google Maps React Component" Tutorial

Fullstack React Google Maps Tutorial

Google Map React Component Tutorial Dolpins

A declarative Google Map React component using React, lazy-loading dependencies, current-location finder and a test-driven approach by the Fullstack React team.

See the demo and accompanying blog post.

Quickstart

First, install the library:

npm install --save google-maps-react
Enter fullscreen mode Exit fullscreen mode

Automatically Lazy-loading Google API

The library includes a helper to wrap around the Google maps API. The GoogleApiWrapper Higher-Order component accepts a configuration object which must include an apiKey. See lib/GoogleApi.js for all options it accepts.

import {GoogleApiWrapper} from 'google-maps-react';
// ...
export class MapContainer extends React.Component {}
export default GoogleApiWrapper({
  apiKey: (YOUR_GOOGLE_API_KEY_GOES_HERE)
})(MapContainer)
Enter fullscreen mode Exit fullscreen mode

Alternatively, the GoogleApiWrapper Higher-Order component can be configured by passing a function that will be called with whe wrapped component's props and should returned the configuration object.

export default GoogleApiWrapper(
  (props) => ({
Enter fullscreen mode Exit fullscreen mode

I love to research how to implement what I need without using third-party libraries and after long research, I found a way to integrate it.

first thing how to get access key to use google maps

firstly, we need to get access key from google cloud google cloud and after login go to the console in the top right corner
console button
If you are new to google cloud service you get a free 300$

then we open a new Project and in the dashboard go to the enable APIs and services button and search for those 3 API:
1.Geocoding API.

2.Maps JavaScript API.

3.Places API.

after adding those 3 APIs we press the hamburger button in the top left corner and go to APIs & Services -> Credentials
then we press the create credentials button and in the select list pick API key and the popup press restrict key
in the Application, restrictions pick HTTP referrers (websites)
then we add our website URL so only from this URL you can call with this key after it we go to API restrictions and pick Restrict key and pick the three APIs we enable earlier and saves it.
the process can take up to 5 min to the key to be activated or take effect after a change of the setting.
you can also see Google video about this if you want another explanation.

The integration

now we start with the fun part and build our react app
The code here is written with a functional component and not a class component but it similar to each other.

create your react app

npm init react-app my-app
Enter fullscreen mode Exit fullscreen mode

Create 2 env files

.env.development and .env.production and put in the project folder(not in the src folder).
there you gonna save your access key to add env var that react will recognize we need to use REACT_APP at the start of every variable like REACT_APP_API_KEY and set it equal to you to access key

REACT_APP_API_KEY = access_key
Enter fullscreen mode Exit fullscreen mode

**Remember if you upload your code with git add in the .gitignore those file

1. Add useRef to your component

we need to useRef because we need to get the element reference in the future code

const googleMapRef = useRef();
<div
     id="google-map"
     ref={googleMapRef}
    style={{ width: '400px', height: '300px' }}/>
Enter fullscreen mode Exit fullscreen mode

2. Write useEffect to implement the script load

we here use useEffect because we want to load the google maps script after the component render

useEffect(() => {
    const googleMapScript = document.createElement('script');
    googleMapScript.src=`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_API_KEY}&libraries=places`;
    googleMapScript.async = true;
    window.document.body.appendChild(googleMapScript);
    googleMapScript.addEventListener('load', () => {
                        getLatLng();
                    });
                })
},[])
you can add at the end of the src &language=en to be only English without this it will be localized.
Enter fullscreen mode Exit fullscreen mode

3. Create google map function

here we see how see the code that will print the map to the element from the ref.

    const createGoogleMap = (coordinates) => {
        googleMap = new window.google.maps.Map(googleMapRef.current, {
            zoom: 16,
            center: {
                lat: coordinates.lat(),
                lng: coordinates.lng(),
            },
            disableDefaultUI: true,
        })
    };
Enter fullscreen mode Exit fullscreen mode

I added isableDefaultUI: true because I wanted to remove the default button that comes with it like in the image below.
Defualt Google Map

4. Get LAT & LNG for the map

in this method, we insert the location place and we get the LAT & LNG of the location and add send the result to the previous function we see, Also as you can see there is Marker so when I print the location it will print it with the red marker
(if you don't use the marker you will see the location without the red marker).

    const getLatLng = () => {
        let lat, lng, placeId;
        new window.google.maps.Geocoder().geocode({ 'address': `${placeName}` }, function (results, status) {
            if (status === window.google.maps.GeocoderStatus.OK) {
                placeId = results[0].place_id;
                createGoogleMap(results[0].geometry.location);
                lat = results[0].geometry.location.lat();
                lng = results[0].geometry.location.lng();
                new window.google.maps.Marker({
                    position: { lat, lng },
                    map: googleMap,
                    animation: window.google.maps.Animation.DROP,
                    title: `${placeName}`
                });
                setGoogleMapInfo({ ...GoogleMapInfo, lat, lng, placeId, isLoading: false, googleMap });
            } else {
                alert('Geocode was not successful for the following reason: ' + status);
            }
        });
    }
Enter fullscreen mode Exit fullscreen mode

without marker:
Google Map Without Marker
with Marker:
Google Map with Marker

5. add everything to one component

const GoogleMap = ({ placeName }) => {
  const googleMapRef = useRef();
  let googleMap;
  useEffect(() => {
    const googleMapScript = document.createElement("script");
    googleMapScript.src = `https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_API_KEY}&libraries=places`;
    googleMapScript.async = true;
    window.document.body.appendChild(googleMapScript);
    googleMapScript.addEventListener("load", () => {
      getLatLng();
    });
  }, []);

  const createGoogleMap = (coordinates) => {
    googleMap = new window.google.maps.Map(googleMapRef.current, {
      zoom: 16,
      center: {
        lat: coordinates.lat(),
        lng: coordinates.lng(),
      },
      disableDefaultUI: true,
    });
  };
  const getLatLng = () => {
    let lat, lng, placeId;
    new window.google.maps.Geocoder().geocode(
      { address: `${placeName}` },
      function (results, status) {
        if (status === window.google.maps.GeocoderStatus.OK) {
          placeId = results[0].place_id;
          createGoogleMap(results[0].geometry.location);
          lat = results[0].geometry.location.lat();
          lng = results[0].geometry.location.lng();
          new window.google.maps.Marker({
            position: { lat, lng },
            map: googleMap,
            animation: window.google.maps.Animation.DROP,
            title: `${placeName}`,
          });
        } else {
          alert(
            "Geocode was not successful for the following reason: " + status
          );
        }
      }
    );
  };
  return (
    <div
      id="google-map"
      ref={googleMapRef}
      style={{ width: "400px", height: "300px" }}
    />
  );
};

Enter fullscreen mode Exit fullscreen mode

There it is easy right!!

As you can see it is super easy to do it and there is no use for this library and you can do it all by yourself
in placeName name try to put something like "Kennedy Space Center Historic Launch Complex 39A"

I hope this was interesting and helpful.
this is my first article and I would glad to get reviews and stuff that I can do to improve the reading environment and how to write it better

Discussion (7)

pic
Editor guide
Collapse
deadmor39411089 profile image
❌ Dead Moroz ❌

I can only second Mulweli's comment. The article not only is extremely hard to follow but has some serious errors in code.

  • unnecessary pair of closing brackets }) in GoogleMap function;
  • undefined variable googleMap in createGoogleMap function;
  • undefined method setGoogleMapInfo in getLatLng function.

It goes without saying that the code is not properly formatted and - as the result - is quite hard to understand. DEV.TO says you have 4 years of experience in FE technologies. I can only assume that actual coding is not included in this timeframe, otherwise it's quite hard to understand why such experienced developer is writing such code and posting it publicly. Sorry if this offended you in some way.

Collapse
talorlanczyk profile image
TalOrlanczyk Author

When I wrote this I didn't notice those mistakes, I code all those 4 years thank you for showing me the problem so I can edit it.
next time I will look up for those mistakes.
it's was just a problem of copy and paste from my source code because I split the code a little so the Component itself will look much more cleaner. so I had to build it up by blocks and I see now it was a big mistake

Collapse
genecodefx profile image
Mulweli

Very very hard to follow

Collapse
talorlanczyk profile image
TalOrlanczyk Author

Thanks for your comment I would like to know what makes you feel like this, so I can change how I write in the future

Collapse
harrydeanstanton profile image
Jan Ancukiewicz

Great stuff! Is it possible to display two maps with this component (with different centers), or at least two markers?

Collapse
talorlanczyk profile image
TalOrlanczyk Author

I think you can do more then one just add new windows.google.maps
Didn't do it but its looks like it gonna work like this

Collapse
yanshiyason profile image
Shiyason

Thank you for sharing! Super useful!