maps icon indicating copy to clipboard operation
maps copied to clipboard

[Bug]: Adding `LocationPuck` causes `onMapIdle` to be called infinitely

Open kainzhong opened this issue 10 months ago • 1 comments

Mapbox Implementation

Mapbox

Mapbox Version

default

React Native Version

0.76.6

Platform

iOS

@rnmapbox/maps version

#main

Standalone component to reproduce

import { StyleSheet, View } from 'react-native';

import React from 'react';
import Mapbox, { LocationPuck } from '@rnmapbox/maps';

Mapbox.setAccessToken('');

const App = () => {

  return (
    <View style={styles.page}>
      <View
        style={styles.container}
      >
        <Mapbox.MapView
          style={styles.map}
          onMapIdle={() => console.log('onMapIdle')}
        >
        <LocationPuck />
        </Mapbox.MapView>
      </View>
    </View>
  );
}

export default App;

const styles = StyleSheet.create({
  page: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  container: {
    height: '100%',
    width: '100%',
  },
  map: {
    flex: 1
  }
})

Observed behavior and steps to reproduce

The reproduction component above is just something I wrote to make the bot open this issue and I have no idea if that works.

You can reproduce this issue by just using the example project in this repo which is a lot easier.

In src/examples/Map/ShowRegionDidChange.js

Add this method:

  onMapIdle(state) {
    console.log("onMapIdle called")
  }

and in render() method, add <LocationPuck /> in that <MapView> component.

Follow the reproduce instructions above. Run the example project, and go to "Show Region Did Change". When the map settles, you'll see

Image

which never stops.

Also if you add this instead:

          <LocationPuck
            puckBearing={"heading"}
            puckBearingEnabled={true}
            pulsing={{
              isEnabled: true,
              color: "teal",
              radius: 30.0,
            }}
          />

you'll see onMapIdle is never called.

Expected behavior

I would expect onMapIdle to be only called once when the map is not moving?

Notes / preliminary analysis

No response

Additional links and references

No response

kainzhong avatar Mar 06 '25 00:03 kainzhong

Could be a dup of #2902 and https://github.com/mapbox/mapbox-maps-android/issues/2116

kainzhong avatar Mar 06 '25 05:03 kainzhong

I have this issue too, added UserLocation and onMapIdle goes on an infinite loop (and heats my phone lol)

my code

<Mapbox.MapView
  ref={mapRef}
  style={styles.map}
  styleURL={Mapbox.StyleURL.Street}
  onMapIdle={handleMapIdle}>

   // enabling this causes meltdown
  {/* <Mapbox.UserLocation visible={true} /> */}
  })}
</Mapbox.MapView>

warmfire540 avatar Oct 18 '25 16:10 warmfire540

I don't think we can do much to fix this. Definition of onMapIdle is quite vague.

Invoked when the Map has entered the idle state. The Map is in the idle state when there are no ongoing transitions and the Map has rendered all available tiles.

In same cases onMapIdle is called when you don't expect it to. Other case onMapIdle is called when you don't expect it.

We should be implementing stuff like Viewport listeners (already implemented). Camera animation listeners (TODO).

https://docs.mapbox.com/android/maps/api/11.15.3/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-lifecycle-listener/?query=interface%20CameraAnimationsLifecycleListener

https://docs.mapbox.com/ios/maps/api/11.15.2/documentation/mapboxmaps/cameraanimationsmanager

And we should deprecate onMapIdle, and people should use more specific observers.

mfazekas avatar Oct 18 '25 16:10 mfazekas

what's the recommended way to know when the map settles down after someone moves it, so we can then fetch data in the viewport? onRegionChange throws deprecation warnings

warmfire540 avatar Oct 18 '25 16:10 warmfire540

@warmfire540 I'm working on a map steady callback. See #4074

mfazekas avatar Nov 09 '25 06:11 mfazekas