maps icon indicating copy to clipboard operation
maps copied to clipboard

[Bug]: Event handlers not called in web environment

Open Jaza opened this issue 1 year ago • 3 comments

Mapbox Implementation

Mapbox

Mapbox Version

default

React Native Version

0.74.1

Platform

Android

@rnmapbox/maps version

10.1.28

Standalone component to reproduce

import React from 'react';
import { useState } from 'react';
import {
  MapState,
  MapView,
  Camera,
} from '@rnmapbox/maps';

const BugReportExample = () => {
  const [_mapState, setMapState] = useState<MapState>({
    properties: {
      center: [0, 0],
      bounds: {
        ne: [0, 0],
        sw: [0, 0],
      },
      zoom: 0,
      heading: 0,
      pitch: 0,
    },
    gestures: {
      isGestureActive: false,
    },
  });

  return (
    <MapView
      style={{flex: 1}}
      onCameraChanged={(_state) => {
        setMapState(_state);
        alert(`${_mapState.properties.center}`);
      }}
      onMapIdle={(_state) => {
        setMapState(_state);
        alert(`${_mapState.properties.center}`);
      }}
    >
      <Camera centerCoordinate={[-74.00597, 40.71427]} zoomLevel={14} />
    </MapView>
  );
};

Observed behavior and steps to reproduce

In Android (Expo app, development build - not Expo Go, not EAS - running in Android Emulator, or running on physical device via USB debugging / adb): alerts appear with correct map location on initial load and on pan / zoom, onCameraChanged / onMapIdle appear to be getting triggered.

In Expo Web: no alerts appear, onCameraChanged / onMapIdle appear to NOT be getting triggered.

Expected behavior

Should be the same in Expo Web as it is in Android, i.e. onCameraChanged / onMapIdle should get triggered.

Notes / preliminary analysis

No response

Additional links and references

Also reported (not by me) at: https://stackoverflow.com/questions/78625575/mapbox-from-rnmapbox-event-handlers-are-not-called-on-web

Jaza avatar Aug 26 '24 10:08 Jaza

+1

ydrea avatar Sep 28 '24 17:09 ydrea

I ended up switching to maplibre-react-native instead, and falling back to react-map-gl with maplibre-gl-js for web. See my Expo MapLibre native + web demo for details.

Jaza avatar Jan 11 '25 03:01 Jaza

@Jaza You can get the mapboxgl.Map instance from ref. From there, you can hook up anything you want from the mapbox-gl pacakge.

There's an example

import WebMapView from '@rnmapbox/maps/src/web/components/MapView';

  const mapRef = useRef<Mapbox.MapView>(null);

  useEffect(() => {
    const eventHandler = onCameraChangedWeb;
    if (Platform.OS === 'web' && mapRef.current) {
      const webMap = mapRef.current as unknown as WebMapView;
      const mapNode = webMap.map as mapboxgl.Map;
      mapNode.on('moveend', eventHandler);
    }
    return () => {
      if (Platform.OS === 'web' && mapRef.current) {
        const webMap = mapRef.current as unknown as WebMapView;
        const mapNode = webMap.map as mapboxgl.Map;
        mapNode.off('moveend', eventHandler);
      }
    };
  }, [mapRef.current]);

return <Mapbox.MapView
        ref={mapRef}
        ...
/>;

Read the source code in @rnmapbox/maps/src/web/components/MapView. It's pretty easy to understand how this pacakge is just a thin wrapper over mapbox-gl.

yuliswe avatar Jan 13 '25 05:01 yuliswe