Flagship1442
Flagship1442

Reputation: 1726

'react-native-maps' becomes extremely slow after adding new marker

I am totally stumped by this problem.

First off this bug only happens in the Android release version of my app. Doesn't seem to affect iOS and I can't reproduce it in debug.

From package.json:

"react-native": "0.62.2",
"react-native-maps": "0.27.1",

I have a map that renders non-customised markers for nearby events. Everything is smooth until a user adds a new event. The event gets added to the server, the app syncs with the server, and the new event is added to the state in Redux. If I switch back to the map view after creating the event then I can see the new marker, but now if I move the map around it's incredibly jerky.

I've spent a couple of days trying to figure this out, and some things I've noticed are:

Suggested solutions I've tried from other posts that haven't fixed the problem/were already implemented:

Relevant code

     // Map.ts

     <View style={styles.container}>
        {/* <Banner bannerState={bannerState} text={bannerText} /> */}
        <MapView
          showsUserLocation
          rotateEnabled={false}
          pitchEnabled={false}
          moveOnMarkerPress={false}
          showsMyLocationButton={false}
          showsTraffic={false}
          showsIndoors={false}
          style={styles.map}
          onRegionChange={this.onRegionChange}
          onRegionChangeComplete={this.onRegionChangeComplete}
          onPoiClick={this.onPoiClick}
          initialRegion={this.initialRegion}
          region={region}
        >
           <ItemMarkers
             shouldUseDetailedMarkers
             key='ITEM_MARKERS'
             items={items}
             makeOnPress={this.makeOnPressItem}
           />
        {/* {this.HighlightedArea()} */}
        </MapView>
      </View>
    const ItemMarkers = (props: {
      items: IMapItem[];
      makeOnPress: (index: number) => VoidFunction;
    }): JSX.Element => {
      const {items, makeOnPress} = props;
    
      const renderMarker = (mapItem: IMapItem, index: number) => {
        const {
          description,
          key,
          title,
          location: {latitude, longitude},
        } = mapItem;
    
        return (
          <DefaultMarker
            key={key}
            latitude={latitude}
            longitude={longitude}
            title={title}
            description={description}
            onPress={makeOnPress(index)}
          />
        );
      };
    
      return <View key='ITEM_MARKERS'>{items.map(renderMarker)}</View>;
    };
    // Marker component that gets rendered within DefaultMarker

    <Marker
      key={props.key}
      stopPropagation
      style={styles.marker}
      identifier={props.key}
      tracksViewChanges={false}
      coordinate={{ latitude, longitude }}
      onPress={props.onPress}
    / >

Let me know if there's other code you'd like to see, and thanks in advance! I don't know what else to try.

Upvotes: 1

Views: 3162

Answers (1)

Flagship1442
Flagship1442

Reputation: 1726

I found a very 'hacky' way around the problem... I give a key to <Map... / > which is tied to the number of events created in the session (i.e. key={MAP_KEY_${numCreatedEvents}}`. This essentially forces the map to completely refresh when new events are added by the user.

It's not a great solution, but it solves my immediate problem. Will mark this as accepted unless someone can suggest something more elegant.

Upvotes: 3

Related Questions