reactjs - 使用 React 和 @googlemaps/js-api-loader 未显示 Google 地图标记
问题描述
我未能在 Gatsby 项目中向我的 Google 地图组件添加标记。我被特别要求不要使用任何第三方库,例如react-google-maps
,所以请不要推荐这些。我要使用@googlemaps/js-api-loader
.
我可以很好地加载地图,但我无法显示标记。它被创建为一个新的google.maps.Marker
就好了,并且记录结果表明它正在正确接收lng
和lat
。我已经尝试了各种各样的事情(承诺、回调、异步/等待、不同的范围等),但似乎在markerMaker
之前完成mapMaker
,即使我试图用作挂钩map
的依赖项。useEffect
我试图将它存储map
为一个状态,因为它正在返回一个承诺,但它仍然只是作为一个承诺返回,所以我现在很困惑。
下面的代码:
import React, { useState, useEffect } from "react"
import { Loader } from "@googlemaps/js-api-loader"
const loader = new Loader({
apiKey: "APIKEY",
version: "weekly",
// libraries: ["places"],
})
const mapOptions = {
center: {
lat: -27.4705,
lng: 153.026,
},
zoom: 12,
}
const mapMaker = async () => {
try {
const google = await loader.load()
const map = await new google.maps.Map(
document.getElementById("map"),
mapOptions
)
console.log("map loaded")
return map
} catch (error) {
console.log(error)
}
}
const markerMaker = async (pos, map) => {
try {
const google = await loader.load()
const marker = new google.maps.Marker({
position: pos,
setMap: map,
title: "test",
})
console.log("marker loaded")
} catch (error) {
console.log(error)
}
}
const GoogleMap = ({ className, practices }) => {
const [map, setMap] = useState({})
useEffect(() => {
setMap(mapMaker())
}, [])
useEffect(() => {
markerMaker({ lat: -27.081149410091783, lng: 152.9497979199946 }, map)
}, [map])
return <div className={className} id="map"></div>
}
export default GoogleMap
任何见解将不胜感激。
解决方案
鉴于没有工作示例,我将假设问题是标记在地图可用之前正在运行。
您运行的似乎有两个不正确的假设:
useEffect(() => setMap(mapMaker(), [])
将状态的值设置mapMaker
为谷歌地图实例的返回值。- 仅在声明第一点中的
useEffect(fn, [maps])
实例后才会运行。
首先,实际发生的是函数mapMaker
是异步的,因此返回一个Pomise
. 因此,您的代码实际上正在做的是将状态设置为Promise {<pending>}
. 为了解决这个问题,您必须将代码更改为:
useEffect(() => {
mapMaker().then(map => setMap(map);
}, [])
// OR if you prefer async / await
const loadMap = async () => {
const map = await mapMaker();
setMaps(map);
}
useEffect(() => {
loadMap()
}, [])
现在,由于第二点,仅此一项并不能解决问题。当您将依赖项传递给useEffect
它时,它将在初始值以及值的每次更改上运行。
因此,您的代码可以markerMaker
并行mapMaker
有效地运行。然后markerMaker
在您设置map
为Promise {<pending>}
第一个 useEffect 时运行第二次。
为了解决这个问题,您需要map
在运行 markerMaker 之前检查是否已将其设置为谷歌地图的实例。
一个快速的解决办法是:
const [map, setMap] = useState(null) // set initial state to null | undefined
useEffect(() => {
if (map !== null) { // check for the initial value
markerMaker({ lat: -27.081149410091783, lng: 152.9497979199946 }, map)
}
}, [map])
你可以在沙盒中玩这个。
推荐阅读
- assembly - 指令集架构的定义是什么?
- python-3.x - 在继续之前打开 kivy 弹出窗口
- python-3.x - 具有列表值的字典理解
- php - 分配 Carbon 日期对象时使用 now() 更新日期字段
- haskell - 使用 Aeson 解析嵌套数组和对象
- python - 如何有效地将 sympy 中的术语分组以进行 lambdafication?
- r - 正则表达式删除特定字符之前的所有数字(在 R 中工作)
- r - 如何将向量除以R中的标量并绘制它
- docker - 豆荚死了。容器在 K8s 1.13 中启动
- github - 如何将协作者添加到特定的 Github 存储库并将其也显示在他们的个人资料中