mapbox / mapbox-gl-geocoder

Geocoder control for mapbox-gl-js using Mapbox Geocoding API
https://mapbox.com/mapbox-gl-js/example/mapbox-gl-geocoder/
ISC License
364 stars 180 forks source link

MaxListenersExceededWarning: Possible EventEmitter memory leak detected. #492

Closed magnusrodseth closed 1 year ago

magnusrodseth commented 1 year ago

I use MapboxGeocoder to find the location based on a lat and lng. I get the following warning in the browser console after moving my marker on the map once:

MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 result listeners added. Use emitter.setMaxListeners() to increase limit
    at _addListener (webpack-internal:///../../node_modules/.pnpm/events@3.3.0/node_modules/events/events.js:211:15)
    at EventEmitter.addListener (webpack-internal:///../../node_modules/.pnpm/events@3.3.0/node_modules/events/events.js:227:10)
    at MapboxGeocoder.on (webpack-internal:///../../node_modules/.pnpm/@mapbox+mapbox-gl-geocoder@5.0.1_mapbox-gl@2.13.0/node_modules/@mapbox/mapbox-gl-geocoder/lib/index.js:1338:24)
    at useMap
...

As you can see, there is an error occurring in my custom hook useMap. This hook looks like this:

const useMap = () => {
  // ...
  const [sensorMarker, setSensorMarker] = useState<mapbox.Marker | null>(null);
  const [location, setLocation] = useState<string | null>(null);

  MapboxGeocoder.on("result", (event) => {
    // Note that this is a MapboxGeocoder event, not a Mapbox event.
    // The types in this library are not well maintained, so we have to cast the result by trial and error.
    if (
      !event.result.place_name ||
      !event.result.geometry.coordinates ||
      !sensorMarker
    ) {
      return;
    }

    const [lng, lat] = event.result.geometry.coordinates as [number, number];
    const location = event.result.place_name as string;

    setLocation(location);
    sensorMarker.setLngLat({ lng, lat });
  });

So, the warning occurring in the browser console is a result of MapboxGeocoder.on("result", ...).

The MapboxGeocoder object is just a simple initialization:

import ExternalMapboxGeocoder from "@mapbox/mapbox-gl-geocoder";

export const MapboxGeocoder = new ExternalMapboxGeocoder({
  accessToken: mapboxgl.accessToken,
  mapboxgl,
  marker: false,
});

Have I set something up incorrectly? Can you give me some guidelines on how to debug this? Should it be wrapped in a useEffect?

UPDATE: Wrapping the MapboxGeocoder.on("result", ...) in a useEffect removed the error, but the location still won't be inferred from the current lat / lng.

magnusrodseth commented 1 year ago

Solved by wrapping MapboxGeocoder.on("result", (event) => { ... }) in a useEffect.