微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

谷歌地图与 react js 钩子集成,地图在更新时闪烁

如何解决谷歌地图与 react js 钩子集成,地图在更新时闪烁

所以我正在做一个项目,我想集成谷歌地图,所以我下载了这些包(反应地理代码和反应谷歌地图)我阅读了他们的文档并在代码沙箱上找到了一段代码来帮助我解决通过集成地图,我将代码从类重构为钩子,但是当使用类组件时,更新位置标记时地图不会闪烁,但是当我更新到钩子时,当我更改位置标记时它开始闪烁,是我的代码还是我的代码重构丢失了任何东西,或者它是如何使用钩子管理状态的,这使得闪烁无法逃避 下面是更新后的代码,这是原始代码 (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 : "",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,area = getArea(addressArray);

            setState((prev) => ({
              ...prev,area: area ? area : ""
            }));
          }
        );
      } catch (e) {
        console.error(e);
      }
    }
    fetchLocation();
    return () => {
      _isMounted = false;
    };
  },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;

解决方法

试试这个,

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;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。