感谢帮助,我被困住了!
我尝试做什么 我显示带有一组标记的谷歌地图。 当我点击标记时,我想向 map 添加一个 Google 圆圈。
发生了什么 当我单击第一个标记时,没有显示圆圈。 但是当我单击第二个标记和更多标记时,它们就会显示!
为什么不起作用 我已经使用 console.log 跟踪了 map 状态值。 问题是,当我第一次进入 MarkkerClicked 函数时,由于未知原因,“map”状态的值为“null”!所以没有创建任何圆。 而且,更奇怪的是,当第一次加载 map 时以及当我单击第二个标记时, map 状态包含一个 map 实例。
你能告诉我我做错了什么吗?当单击第一个标记时, map 值设置为空?
我的组件:
import { GoogleMap, MarkerF, useJsApiLoader } from "@react-google-maps/api";
import Box from '@mui/material/Box';
import { useSelector } from 'react-redux'
let mapCircle1 = null
export default function MapPage() {
// The array of markers is in the REDUX store
const selectMarkersArray = state => state.markersArray
const markersArray = useSelector(selectMarkersArray)
// This state contains the selected marker (or null if no marker selected)
const [selectedMarker, setSelectedMarker] = useState(null);
// Options for GoogleMaps
let center = {
lat: 43.3318,
lng: 5.0550
}
let zoom = 15
const containerStyle = {
width: "100%",
height: "100%"
}
// GoogleMaps loading instructions
const { isLoaded } = useJsApiLoader({
id: 'google-map-script',
googleMapsApiKey: "MY-GOOGLE-KEY"
})
const [map, setMap] = useState(null)
const onLoad = useCallback(function callback(map) {
setMap(map)
console.log('map value in onLoad :')
console.log(map)
}, [])
const onUnmount = useCallback(function callback(map) {
setMap(null)
}, [])
// Function executed when a marker is clicked
function markerClicked(props) {
console.log('map value in markerClicked :')
console.log(map)
// I create a new Circle data
let circleOption1 = {
fillColor: "#2b32ac ",
map: map,
center: {lat:props.marker.spotLatitude, lng:props.marker.spotLongitude},
radius: props.marker.spotCircleRadius,
};
mapCircle1 = new window.google.maps.Circle(circleOption1);
// I update the selecte marker state
setSelectedMarker({...props.marker})
}
return (isLoaded ? (
<Box height="80vh" display="flex" flexDirection="column">
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={zoom}
onLoad={onLoad}
onUnmount={onUnmount}
>
{markersArray.map((marker, index) => {
return (
<MarkerF
key={index.toString()}
position={{lat:marker.spotLatitude, lng:marker.spotLongitude}}
onClick={() => markerClicked({marker:marker})}
>
</MarkerF>
)
})}
</GoogleMap>
</Box>
) : <></>
)
};
以及console.log(加载 map 时记录第一个日志,单击第一个标记时记录第二个日志,单击另一个标记时记录第三个日志):
map value in onLoad :
jj {gm_bindings_: {…}, __gm: hda, gm_accessors_: {…}, mapCapabilities: {…}, renderingType: 'UNINITIALIZED', …}
map value in markerClicked :
null
map value in markerClicked :
jj {gm_bindings_: {…}, __gm: hda, gm_accessors_: {…}, mapCapabilities: {…}, renderingType: 'RASTER', …}```
最佳答案
这可能是因为您没有使用 State Hooks 和 <Circle />
用于渲染/更新圆圈的组件
我能够在codesandbox上重现您的代码并确认map
确实正在返回null
每次标记点击。我仍然不确定为什么会发生这种情况,但我设法修复了它,并在通过利用圆圈的 State Hooks 修改代码后,即使在第一次单击标记时也成功渲染了一个圆圈,并且还使用 <Circle />
组件按照react-google-maps/api library docs .
我只是设法硬编码了一些东西,因为我没有使用 redux 来重现你的代码,但我所做的一件事是创建一个 circles
数组状态 Hook :
// this array gets updated whenever you click on a marker
const [circles, setCircles] = useState([
{
id: "",
center: null,
circleOptions: {
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
clickable: false,
draggable: false,
editable: false,
visible: true,
radius: 100,
zIndex: 1
}
}
]);
只需确保添加 useState
关于您的导入。
然后为了演示,我硬编码了一个标记数组:
// This could be your array of marker using redux,
// I just hardcoded this for demonstration
const markersArray = [
{
id: 1,
position: { lat: 43.333194, lng: 5.050184 }
},
{
id: 2,
position: { lat: 43.336356, lng: 5.053353 }
},
{
id: 3,
position: { lat: 43.331609, lng: 5.056403 }
},
{
id: 4,
position: { lat: 43.328806, lng: 5.058998 }
}
];
然后这是我的markerClicked
函数看起来像:
// Function executed when a marker is clicked
const markerClicked = (marker) => {
console.log("map value on marker click: ");
console.log(map);
// This stores the marker coordinates
// in which we will use for the center of your circle
const markerLatLng = marker.latLng.toJSON();
// this will update our circle array
// adding another object with different center
// the center is fetched from the marker that was clicked
setCircles((prevState) => {
return [
...prevState,
{
id: "",
center: markerLatLng,
circleOptions: {
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
clickable: false,
draggable: false,
editable: false,
visible: true,
radius: 100,
zIndex: 1
}
}
];
});
// this is for you to see that the circles array is updated.
console.log(circles);
};
请注意 onClick
<MarkerF />
的属性自动返回一个参数,其中包括标记的坐标和其他内容,您可以尝试使用 console.log
如果你想检查的话。还要确保您在 onClick
上输入的值等于单独的函数名称。在这种情况下,它是 markerClicked
,稍后您就会看到。
注意:我还添加了 mapClicked
函数使您能够清除圆数组。
Please see proof of concept sandbox below.
然后这就是我渲染 <GoogleMap />
的方式组件 <MarkerF />
和<Circle />
组件作为其子级。
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={zoom}
onLoad={onLoad}
onUnmount={onUnmount}
onClick={mapClicked}
>
{markersArray.map((marker, index) => {
return (
<MarkerF
key={index.toString()}
position={{ lat: marker.position.lat, lng: marker.position.lng }}
onClick={markerClicked}
></MarkerF>
);
})}
{/* This maps through the circles array, so when the array gets updated,
another circle is added */}
{circles.map((circle, index) => {
return (
<Circle
key={index.toString()}
// required
center={circle.center}
// required
options={circle.circleOptions}
/>
);
})}
</GoogleMap>
通过所有这些,标记单击时的 map 值不会返回 null,并且即使在第一次标记单击时也会呈现一个圆圈。
这是一个概念验证沙箱,供您检查并了解其工作原理(确保使用您自己的 API key 进行测试):https://codesandbox.io/s/proof-of-concept-show-circle-on-marker-click-s175wl?file=/src/Map.js
Note: There's some weird offset between the marker and the circle if you zoom out too far, but seems fine when you zoom in. I have encountered this on some previous questions here in SO when rendering polylines and I don't know why is that or how to fix it.
话虽如此,希望这会有所帮助!
关于reactjs - 谷歌地图 API : why does my map state become null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75153679/