Reputation: 380
I have a gatsby app that used google maps api. I am loading both useRef and useEffect to load the map. useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component. Here's my code:
import React, { useRef, useEffect } from "react"
import MapMarker from "../assets/images/logos/map-marker.png"
const Map = () => {
const map = useRef(null)
useEffect(()=>{
if(typeof window !== "undefined"){
window.initMap = function() {
const map = new window.google.maps.Map(map.current, {
center: {
lat: 142.1463554,
lng: 121.5245996
},
zoom: 10,
styles: [{"featureType":"water","elementType":"geometry","stylers":[{"color":"#d3d3d3"},{"lightness":50}]},{"featureType":"landscape","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#ffffff"},{"lightness":17}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#ffffff"},{"lightness":29},{"weight":0.2}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":18}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":16}]},{"featureType":"poi","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":21}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#dedede"},{"lightness":21}]},{"elementType":"labels.text.stroke","stylers":[{"visibility":"on"},{"color":"#ffffff"},{"lightness":16}]},{"elementType":"labels.text.fill","stylers":[{"saturation":50},{"color":"#000000"},{"lightness":40}]},{"elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"color":"#f2f2f2"},{"lightness":19}]},{"featureType":"administrative","elementType":"geometry.fill","stylers":[{"color":"#4c4c4c"},{"lightness":20}]},{"featureType":"administrative","elementType":"geometry.stroke","stylers":[{"color":"#4c4c4c"},{"lightness":17},{"weight":1.2}]}]
})
new window.google.maps.Marker({
position: { lat: 112.1463554, lng: 130.5245993 },
icon: MapMarker,
animation: window.google.maps.Animation.BOUNCE,
map: map
});
}
}
return () => map.current = null
}, [])
return (
<div id="map-container" data-aos="fade-up">
<div className="container-fluid">
<div className="row">
<div className="col-lg-12 col-12 pl-0 pr-0">
<div className="google-map">
<div id="map" ref={map}></div>
</div>
</div>
</div>
</div>
</div>
)
}
export default Map
When I loaded my gatsby app, it returned:
Unhandled Rejection (TypeError): Cannot read property 'current' of undefined
window.initMap
C:/Users/Read/Desktop/gatsby/src/components/Map.js:12
9 |
10 | if(typeof window !== "undefined"){
11 | window.initMap = function() {
> 12 | const map = new window.google.maps.Map(map.current, {
13 | center: {
14 | lat: 11.1463554,
15 | lng: 110.5245996
Any idea how to fix this? Please help!
Upvotes: 1
Views: 890
Reputation: 29305
You have naming issues when accessing the reference, since your map
and your reference has the same name, it leads to this issue because of the scope. Change it to:
import React, { useRef, useEffect } from "react"
import MapMarker from "../assets/images/logos/map-marker.png"
const Map = () => {
const mapRef = useRef(null)
useEffect(()=>{
if(typeof window !== "undefined"){
window.initMap = function() {
const map = new window.google.maps.Map(mapRef.current, {
center: {
lat: 11.1463554,
lng: 110.5245996
},
zoom: 10,
styles: [{"featureType":"water","elementType":"geometry","stylers":[{"color":"#d3d3d3"},{"lightness":50}]},{"featureType":"landscape","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#ffffff"},{"lightness":17}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#ffffff"},{"lightness":29},{"weight":0.2}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":18}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":16}]},{"featureType":"poi","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":21}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#dedede"},{"lightness":21}]},{"elementType":"labels.text.stroke","stylers":[{"visibility":"on"},{"color":"#ffffff"},{"lightness":16}]},{"elementType":"labels.text.fill","stylers":[{"saturation":50},{"color":"#000000"},{"lightness":40}]},{"elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"color":"#f2f2f2"},{"lightness":19}]},{"featureType":"administrative","elementType":"geometry.fill","stylers":[{"color":"#4c4c4c"},{"lightness":20}]},{"featureType":"administrative","elementType":"geometry.stroke","stylers":[{"color":"#4c4c4c"},{"lightness":17},{"weight":1.2}]}]
})
new window.google.maps.Marker({
position: { lat: 112.1463554, lng: 130.5245993 },
icon: MapMarker,
animation: window.google.maps.Animation.BOUNCE,
map: map
});
}
}
return () => mapRef.current = null
}, [])
return (
<div id="map-container" data-aos="fade-up">
<div className="container-fluid">
<div className="row">
<div className="col-lg-12 col-12 pl-0 pr-0">
<div className="google-map">
<div id="map" ref={mapRef}></div>
</div>
</div>
</div>
</div>
</div>
)
}
export default Map
Upvotes: 1