我有一个使用react谷歌地图的react应用程序。当用户移动地图时,我希望它的标记固定在地图的中心。但在我的情况下,每当拖动事件发生时,地图就会立即刷新。
父组件:
import React, { useState, useEffect } from 'react';
import Map from './Map';
export default function Parent() {
const [mapCenter, setMapCenter] = useState(undefined);
const [markerPosition, setMarkerPosition] = useState(undefined);
useEffect(()=>navigator.geolocation.getCurrentPosition(position =>
{
setMapCenter({lat:position.coords.latitude, lng:position.coords.longitude})
setMarkerPosition({lat:position.coords.latitude, lng:position.coords.longitude})
}
),[])
return(
<div>
{ mapCenter && <Map mapCenter={mapCenter} setMapCenter={setMapCenter} markerPosition={markerPosition} setMarkerPosition={setMarkerPosition} />}
</div>
)
}
以及地图组件:
import React from 'react';
import { GoogleMap, Marker, withGoogleMap } from "react-google-maps";
export default function Map(props) {
let mapRef;
let markerRef;
const WrappedMap = withGoogleMap(() =>
<GoogleMap ref={(ref) => mapRef = ref} center={props.mapCenter} zoom={16} onDrag={()=>{
const newCenter = mapRef.getCenter().toJSON();
props.setMarkerPosition(newCenter);
props.setMapCenter(newCenter)
}}>
<Marker ref={(ref) => markerRef = ref } position={props.markerPosition} draggable={false}/>
</GoogleMap>
);
return (
<div style={{ height: "50vh", width: "50vh" }}>
<WrappedMap
loadingElement={<div style={{ height: "100%" }} />}
containerElement={<div id="map" style={{ height: "100%" }} />}
mapElement={<div style={{ height: "100%" }} />}
/>
</div>
)
}
我预计,当用户拖动地图时,父对象的状态会得到更新,标记会移动到新位置,但它并没有像我预期的那样工作。我在这里错过了什么?
要实现您的用例,在父组件中,您需要使用handleChangeCenter
函数来设置中心和标记的新值,然后将onChange
参数传递给调用handleChangeCenter
函数的子组件。
在您的子组件中,您可以使用onDragEnd
和onDragEnd
,而不是<GoogleMap/>
对象的onDrag
函数,您将调用一个handleChange
函数,该函数在dragEnd上获取地图的当前中心坐标,并将新值传递给onChange
的道具,以更改中心和标记的状态。
下面是一个示例代码和一个代码片段:
parent.js
import React, { useState, useEffect } from 'react';
import Map from './Map';
export default function Parent() {
const [mapCenter, setMapCenter] = useState(undefined);
const [markerPosition, setMarkerPosition] = useState(undefined);
function handleChangeCenter(newValue) {
setMapCenter(newValue);
setMarkerPosition(newValue)
}
useEffect(()=>navigator.geolocation.getCurrentPosition(position =>
{
setMapCenter({lat:position.coords.latitude, lng:position.coords.longitude})
setMarkerPosition({lat:position.coords.latitude, lng:position.coords.longitude})
}
),[])
return(
<div>
{ mapCenter && <Map mapCenter={mapCenter} markerPosition={markerPosition} onChange={handleChangeCenter} />}
</div>
)
}
Map.js
import React from 'react';
import { GoogleMap, Marker, withGoogleMap } from 'react-google-maps';
export default function Map(props) {
let mapRef;
function handleChange() {
// Here, we invoke the callback with the new value
const newCenter = mapRef.getCenter().toJSON();
console.log(newCenter);
props.onChange(newCenter);
}
const WrappedMap = withGoogleMap(() => (
<GoogleMap
ref={(ref) => (mapRef = ref)}
center={props.mapCenter}
zoom={16}
onDragEnd={handleChange}
>
<Marker position={props.markerPosition} draggable={false} />
</GoogleMap>
));
return (
<div style={{ height: '50vh', width: '50vh' }}>
<WrappedMap
loadingElement={<div style={{ height: '100%' }} />}
containerElement={<div id="map" style={{ height: '100%' }} />}
mapElement={<div style={{ height: '100%' }} />}
/>
</div>
);
}