Cannot clear route from DirectionRenderer ReactJS with @react-google-maps.api

624 Views Asked by At

I'm trying to make a simple routing with google API and @react-google-api library, I success to show route between 2 points, but when I try to remove the route, the route cannot be removed, here's my code :

const calculateRoute = async () => {
    let placeServices = new google.maps.places.PlacesService(map);
    const result = await directionService.route({
      origin: {lat: -6.914864,lng: 107.608238},
      destination: {lat: -6.814864,lng: 107.608238},
      travelMode: google.maps.TravelMode.DRIVING,
    });
    setDirection(result);
  }

and this my code to clear the route :

const clearRoute = async () => {
    setDirection(null)
  }

and this is my code to rendering a route :

 <GoogleMap
        mapContainerStyle={{
              height: '100vh',
              width: '60vw',
            }}
            zoom={14}
            center={center}
            onLoad={(map) => onLoad(map)}
          >
            {placeData.map((item, index) => (
              <MarkerF
                key={index}
                position={{
                  lat: item.geometry.location.lat(),
                  lng: item.geometry.location.lng(),
                }}
              />
            ))}
            {
              direction &&
                <DirectionsRenderer directions={direction}/>
            }
          </GoogleMap>

direction is a state from a useState [direction, setDirection]

Screenshot: When route is show enter image description here

When I trying to remove route enter image description here

it's only reduce opacity from route

2

There are 2 best solutions below

0
On

React development mode renders twice by default. To solve this, you can remove React StrictMode in the index.js file or npm build the project as follows

npm install -g serve
serve -s build
0
On

This post helped me uncover the answer: How can I delete previous route on google maps?

It appears that when you use (most?) new google.maps.Whatever(), youll want to store it in a useRef() and use that reference throughout the life of the component.

So for example, the following is now replacing prior directions/routes when i changes the markers (which turn into origin, waypoints, destination).

It appears whenever you call new google.maps.Whatever(), any side-effect that might on the map persists until you call setMap(null) on it (which will detach it from the map, or if you reset its configuration (which is what im doing in the example below).

I was getting some oddities with the ref being "ready for use" so there might be better ways to initialize it.

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

  useDeepCompareEffect(() => {
    async function getDirections() {
      if (directionsService?.current == null) return;

      const response = await directionsService.current.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]);

  useEffect(() => {
    if (!directionsRenderer?.current?.setDirections) return;

    directionsRenderer.current.setMap(map);
    directionsRenderer.current.setDirections(directionsResponse);
  }, [directionsResponse]);

  return (
    <GoogleMap
      mapContainerStyle={{ width: "100%", height: "100%" }}
      zoom={13}
      onLoad={(map) => setMap(map)}
      onUnmount={() => setMap(null)}
    ></GoogleMap>
  );
}