谷歌地图与反应 js 挂钩的集成,地图在更新时闪烁
Posted
技术标签:
【中文标题】谷歌地图与反应 js 挂钩的集成,地图在更新时闪烁【英文标题】:google maps integration with react js hooks, map flickers on update 【发布时间】:2021-09-27 01:34:20 【问题描述】:所以我正在做一个项目,我想集成谷歌地图,所以我下载了这些包(反应地理代码和反应谷歌地图)我阅读了他们的文档并在代码沙箱上找到了一段代码来帮助我解决问题通过集成地图,我将代码从类重构为钩子,但是当使用类组件时,地图在更新位置标记时不会闪烁,但是当我更新到钩子时,当我更改位置标记时它开始闪烁,是我的代码还是我的代码重构遗漏任何东西,或者是如何使用钩子管理状态,这使得闪烁不可避免 下面是更新的代码,这是原始代码 (https://codesandbox.io/s/modest-platform-g8mjx?file=/src/LocationSearchModal.js) 知道为什么我有 2 个标记吗?
import React, useCallback, useEffect, useState from "react";
import
withGoogleMap,
GoogleMap,
withScriptjs,
InfoWindow,
Marker
from "react-google-maps";
import Geocode from "react-geocode";
import Autocomplete from "react-google-autocomplete";
import Card from "react-bootstrap";
Geocode.setApiKey("googleAPIKEYHERE");
Geocode.enableDebug();
const LocationSearchModal = () =>
const [state, setState] = useState(
address: "",
city: "",
area: "",
state: "",
zoom: 15,
height: 400,
mapPosition:
lat: 55,
lng: 55
,
markerPosition:
lat: 55,
lng: 55
);
const getCity = useCallback((addressArray) =>
let city = "";
for (let i = 0; i < addressArray.length; i++)
if (
addressArray[i].types[0] &&
"administrative_area_level_2" === addressArray[i].types[0]
)
city = addressArray[i].long_name;
return city;
, []);
const getArea = useCallback((addressArray) =>
let area = "";
for (let i = 0; i < addressArray.length; i++)
if (addressArray[i].types[0])
for (let j = 0; j < addressArray[i].types.length; j++)
if (
"sublocality_level_1" === addressArray[i].types[j] ||
"locality" === addressArray[i].types[j]
)
area = addressArray[i].long_name;
return area;
, []);
const getState = useCallback((addressArray) =>
let state = "";
for (let i = 0; i < addressArray.length; i++)
for (let i = 0; i < addressArray.length; i++)
if (
addressArray[i].types[0] &&
"administrative_area_level_1" === addressArray[i].types[0]
)
state = addressArray[i].long_name;
return state;
, []);
const onChange = (event) =>
setState( [event.target.name]: event.target.value );
;
const onInfoWindowClose = (event) => ;
const onMarkerDragEnd = useCallback((event) =>
const newLat = event.latLng.lat(),
newLng = event.latLng.lng();
setState((prev) => (
...prev,
mapPosition:
lat: newLat,
lng: newLng
,
markerPosition:
lat: newLat,
lng: newLng
));
Geocode.fromLatLng(newLat, newLng).then(
(response) =>
// const address = response.results[0].formatted_address,
// addressArray = response.results[0].address_components,
// city = getCity(addressArray),
// area = getArea(addressArray),
// state = getState(addressArray);
console.log(response);
const address = response.results[0].formatted_address;
let city, state, area;
for (
let i = 0;
i < response.results[0].address_components.length;
i++
)
for (
let j = 0;
j < response.results[0].address_components[i].types.length;
j++
)
switch (response.results[0].address_components[i].types[j])
case "locality":
city = response.results[0].address_components[i].long_name;
break;
case "administrative_area_level_1":
state = response.results[0].address_components[i].long_name;
break;
case "country":
area = response.results[0].address_components[i].long_name;
break;
setState((prev) => (
...prev,
address: address ? address : "",
area: area ? area : "",
city: city ? city : "",
state: state ? state : ""
));
,
(error) =>
console.error(error);
);
, []);
const onPlaceSelected = useCallback(
(place) =>
console.log("plc", place);
const address = place.formatted_address,
addressArray = place.address_components,
city = getCity(addressArray),
area = getArea(addressArray),
state = getState(addressArray),
latValue = place.geometry.location.lat(),
lngValue = place.geometry.location.lng();
console.log("latvalue", latValue);
console.log("lngValue", lngValue);
// Set these values in the state.
setState((prev) => (
address: address ? address : "",
area: area ? area : "",
city: city ? city : "",
state: state ? state : "",
markerPosition:
lat: latValue,
lng: lngValue
,
mapPosition:
lat: latValue,
lng: lngValue
));
,
[getArea, getCity, getState]
);
const AsyncMap = withScriptjs(
withGoogleMap((props) =>
console.log(props);
return (
<GoogleMap
defaultZoom=state.zoom
defaultCenter=
lat: state.markerPosition.lat,
lng: state.markerPosition.lng
>
/*Marker*/
<Marker
google=window.google
name="Dolores park"
draggable=true
onDragEnd=onMarkerDragEnd
position=
lat: state.markerPosition.lat,
lng: state.markerPosition.lng
/>
<InfoWindow
onClose=onInfoWindowClose
position=
lat: state.markerPosition.lat,
lng: state.markerPosition.lng
>
<div>
<span style= padding: 0, margin: 0 >state.address</span>
</div>
</InfoWindow>
<Marker />
/* <MarkerWithLabel
position= lat: -34.397, lng: 150.644
labelAnchor=new google.maps.Point(0, 0)
labelStyle= backgroundColor: "yellow", fontSize: "32px", padding: "16px"
>
<div>Hello There!</div>
</MarkerWithLabel> */
/* For Auto complete Search Box */
<Autocomplete
style=
width: "100%",
height: "40px",
paddingLeft: "16px",
marginTop: "2px",
marginBottom: "2rem"
onPlaceSelected=onPlaceSelected
types=["(regions)"]
/>
</GoogleMap>
);
)
);
useEffect(() =>
let _isMounted = true;
function fetchLocation()
try
Geocode.fromLatLng(state.mapPosition.lat, state.mapPosition.lng).then(
(response) =>
const address = response.results[0].formatted_address,
addressArray = response.results[0].address_components,
city = getCity(addressArray),
state = getState(addressArray),
area = getArea(addressArray);
setState((prev) => (
...prev,
address: address ? address : "",
city: city ? city : "",
area: area ? area : ""
));
);
catch (e)
console.error(e);
fetchLocation();
return () =>
_isMounted = false;
;
, [getArea, getCity, getState]);
return (
<div style= padding: "1rem", margin: "0 auto", maxWidth: 1000 >
<h1>Campus Guide Routes</h1>
<Card bordered>
<Card.Text label="City">state.city</Card.Text>
<Card.Text label="Area">state.area</Card.Text>
<Card.Text label="State">state.state</Card.Text>
<Card.Text label="Address">state.address</Card.Text>
</Card>
<AsyncMap
googleMapURL="https://maps.googleapis.com/maps/api/js?key=googleApiKeyHere&libraries=places"
loadingElement=<div style= width: "100%", height: `100%` />
containerElement=
<div style= width: "100%", height: state.height />
mapElement=<div style= width: "100%", height: `100%` />
/>
</div>
);
;
export default LocationSearchModal;
【问题讨论】:
什么时候闪烁?当你关闭信息窗口? 当你改变标记位置时 【参考方案1】:试试这个,
const AsyncMap = withScriptjs(
withGoogleMap((props) =>
return (
<GoogleMap
defaultZoom=state.zoom
defaultCenter=
lat: state.markerPosition.lat,
lng: state.markerPosition.lng
id="map-container"
>
.....
将 css 添加到地图容器
#map-container
overflow-anchor:none;
【讨论】:
不幸的是我之前没有在 react 中使用 ids,我是否创建一个文件并像这样导入它从 "../../../../../src/资产/scss/test.css";然后使用这个 id=styles["map-container"] 并知道为什么我有 2 个标记 确保 css 将根据您的代码结构应用于您的代码 我将 css 添加到 css 文件并导入,但似乎没有任何效果以上是关于谷歌地图与反应 js 挂钩的集成,地图在更新时闪烁的主要内容,如果未能解决你的问题,请参考以下文章