Next.js/React 18,Google Maps JS API未清除先前的Map状态

7fhtutme  于 2023-05-06  发布在  React
关注(0)|答案(1)|浏览(138)

我有一个React 18/Next.js应用程序,它有一个GoogleMap。
我有一个共享的Map组件,我将与Map相关的对象传递给它来Map,当前是一个latLng坐标数组,我用它来生成方向。此数组的顺序在Map组件之外进行管理。
假设我传入一个包含2个坐标(A,B)的数组来获取方向。我所看到的是在Map的初始“加载”上(在刷新浏览器之后)-坐标正确地绘制了从A -〉B的单一路线线。
然而,当我现在将坐标的顺序更改为[ B,A ](这将使B成为方向原点,A成为目的地)时,GoogleMap会更新,它会从B -〉A绘制路线,但旧路线(A -〉B)仍然显示在Map上。我检查了响应,两个(A-〉B和B-〉A)都有一个路由。刷新浏览器将渲染单条管线。此外,如果我添加更多的坐标到 prop 列表,他们显示在Map上(w/新的路线多边形线),但如果我删除一个航点-它不会删除该标记。就像我只能在Map上添加,不能从Map上删除。
有什么想法吗

import { useState, useCallback, useEffect, useRef } from "react";
import useDeepCompareEffect from "use-deep-compare-effect";
import { GoogleMap, DirectionsRenderer, MarkerF } from "@react-google-maps/api";

export function MarkerMap({ markers }) {
  const [map, setMap] = useState(/** @type google.maps.Map */ (null));
  const [directionsResponse, setDirectionsResponse] = useState(null);

  const center = markers[0];

  useDeepCompareEffect(() => {
    console.log("markers changed", markers);
    async function getDirections() {
      const directionsService = new window.google.maps.DirectionsService();
      const response = await directionsService.route({
        origin: markers[0],
        destination: markers[markers.length < 2 ? 0 : markers.length - 1],
        travelMode: window.google.maps.TravelMode.DRIVING,
        optimizeWaypoints: false,
        waypoints:
          markers.length > 2
            ? markers.slice(1, -1).map((m) => ({ location: m, stopover: true }))
            : [],
      });
      setDirectionsResponse(response);
    }
    if (markers?.length > 1) {
      getDirections();
    }
  }, [markers]);

  return (
    <GoogleMap
      mapContainerStyle={{ width: "100%", height: "100%" }}
      center={center}
      zoom={13}
      onLoad={(map) => setMap(map)}
      onUnmount={() => setMap(null)}
    >
      {directionsResponse && (
        <DirectionsRenderer
          options={{
            preserveViewport: true,
            draggable: false,
            hideRouteList: false,
            suppressMarkers: false,
            map: map,
            routeIndex: 0,
            polylineOptions: {
              map: map,
              strokeColor: "#FF0000",
              strokeWeight: 4,
            },
            suppressBicyclingLayer: true,
            suppressPolylines: false,
            markerOptions: {
              label: "Sup dude",
            },
          }}
          directions={directionsResponse}
        />
      )}

      {!directionsResponse &&
        markers?.map((marker, i) => <MarkerF key={i} position={marker} />)}
    </GoogleMap>
  );
}
apeeds0o

apeeds0o1#

我发现我不能使用组件。相反,我必须手动创建DirectionsRenderer对象的ref,并在组件的整个生命周期中使用它。
所以...

const directionsRenderer = useRef(new google.maps.DirectionsRenderer());
...
useEffect(() => { 
   .. look stuff up using the directions service.

   directionsRenderer.setMap(map);
   directionsRenderer.setDirections(directionsResponse);

});

问题似乎是(我猜,正如你所料)当你调用new google.maps.Whatever()时,它创建了一个新的类示例,而任何以前的示例都没有“断开连接”。所以你只要在Map上不断添加方向就行了。如果你跟踪以前的示例,你可以在它们上设置Map(null)来从Map中删除它们的副作用--但是只获取对象的引用,并在状态改变时更新相同的引用似乎更简单/更常见。

相关问题