[Bug]: Event handlers not called in web environment
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
+1
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
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.