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.
fullstackreact / google-maps-react
Companion code to the "How to Write a Google Maps React Component" Tutorial
Google Map React Component Tutorial
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
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)
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) => ({
…
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
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
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
**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' }}/>
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.
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,
})
};
I added isableDefaultUI: true because I wanted to remove the default button that comes with it like in the image below.
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);
}
});
}
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" }}
/>
);
};
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
Top comments (14)
One year passed since your article was written, and it's still true that most articles on using Google Maps APIs with React assume the use of
google-map-react
.Like you I try not to rely on third-party libraries. And also like you, after figuring out how, I've written a similar article to yours, but in my case with Next.js. ;-)
dev.to/masakudamatsu/3-gotchas-of-...
Thanks I read your article its great
I can only second Mulweli's comment. The article not only is extremely hard to follow but has some serious errors in code.
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.
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
You should have added how to get one's current location
Great idea.
even thought to make this basically there are services that by an api tel you where you are but can be un accurate
and by the user approve the geolocation
like in mobile that you need to approve location to access or it wont work
It will work if the user approve it
As almost every api.
Basically you get lat and lng and then you put it as cord
Very very hard to follow
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
Great stuff! Is it possible to display two maps with this component (with different centers), or at least two markers?
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
Amazing post!
Thank you for sharing! Super useful!