JustFly1984 / react-google-maps-api

React Google Maps API
MIT License
1.79k stars 438 forks source link

React Error: Maximum update depth exceeded after navigating back & forth with useJsApiLoader #3312

Open alvalau opened 10 months ago

alvalau commented 10 months ago

Your Environment

os: mac

node --version: v21.1.0

react version: 18.2.0

nextjs version: 13.5.4

@react-google-maps/api version: 2.19.2

How does it behave?

I'm using NextJs, the useJsApiLoader is working just fine except if I use the browser's back & next button to navigate between 2 pages.

Steps to reproduce the error

  1. go to the page that has the integration of google map. (no error)
  2. use browser's back button to leave the page
  3. use browser's forward button to reenter the page. (has error : Maximum update depth exceeded)

Remarks

Here is some what my component looks like:

const OurLocationMapView = ({ lng }: OurLocationMapViewProps) => {
  const [map, setMap] = useAtom(mapAtom);
  const [, setMapWrapper] = useAtom(mapWrapperAtom);
  const [maxZoom, setMaxZoom] = React.useState(15);
  const [center] = React.useState({
    lat: 22.308,
    lng: 114.178,
  });
  const { t } = useTranslation(lng, 'navbar');

  const { isLoaded, loadError } = useLoadScript({
    id: 'google-map-script',
    googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAP_API_KEY as string,
    language: lng,
  });

  const [stores] = useAtom(storesAtom);
  const [selectedStore, setSelectedStore] = useAtom(selectedStoreAtom);

  const onLoad = React.useCallback(function callback(map: any) {
    const bounds = new window.google.maps.LatLngBounds(center);
    map.fitBounds(bounds);

    setMap(map);

    if (timer) clearTimeout(timer);

    timer = setTimeout(() => {
      setMaxZoom(20);
    }, 1000);
  }, []);

  const onUnmount = React.useCallback(function callback(map: any) {
    setMap(null);
    if (timer) clearTimeout(timer);
  }, []);

  if (!isLoaded || loadError) return null;

  return (
    <div
      id={'store-location-map'}
      ref={(ref) => setMapWrapper(ref)}
      className={'sticky top-0 h-[65svh] w-full xl:h-[100svh]'}
    >
      <GoogleMap
        mapContainerStyle={containerStyle}
        center={center}
        onLoad={onLoad}
        onUnmount={onUnmount}
        options={{
          styles: [...styleArray],
          clickableIcons: false,
          mapTypeControl: false,
          maxZoom,
        }}
      >
       {/* some markers & infowindow */}
    </div>
  )
}

I have tried removing the setters inside the onLoad handler, but the error still persist.

How should it behave correctly?

The error should not occur if using browser back & forward button.