You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using react-native-maps with dynamic/changing Marker children arrays, memoization appears not enough to prevent render flicker.
I suspect from reading the native source code that this may be caused by annotations being added and removed on the native side, instead of preserving existing annotations added. More specifically, I think on the native side you may be receiving insertReactSubview and removeReactSubview when indexes change for a subview, even when that subview's reference is not changing.
After trying to debug and work around this issue, I found that explicitly passing an array of children at fixed indices, I can add and remove children without seeing subview flicker.
importReact,{useEffect,useState}from'react';importMapView,{Marker}from'react-native-maps';functionshuffleArray(array){for(leti=array.length-1;i>0;i--){constj=Math.floor(Math.random()*(i+1));[array[i],array[j]]=[array[j],array[i]];}}exportdefaultfunctionApp(){const[markers,setMarkers]=useState([{latitude: 37.8067698,longitude: -122.4578827},{latitude: 37.7735338,longitude: -122.4635475},{latitude: 37.7552137,longitude: -122.4405449},{latitude: 37.8047354,longitude: -122.4206322},{latitude: 37.7858175,longitude: -122.5035452},]);useEffect(()=>{setInterval(()=>{// if you comment out the following shuffleArray line, the flickering stops.shuffleArray(markers);setMarkers([...markers]);},1000);},[]);return(<MapViewstyle={{flex: 1}}googleRenderer="LEGACY"initialRegion={{longitude: -122.4194,latitude: 37.7749,latitudeDelta: 0.1,longitudeDelta: 0.2,}}>{markers.map((coordinate)=>(<Markerkey={`marker_${coordinate.latitude}_${coordinate.longitude}`}coordinate={coordinate}tracksViewChanges={false}/>))}</MapView>);}
RPReplay_Final1711993263.MP4
Steps to reproduce
Load the sample code provided. Notice that the library re-renders Markers with a flicker instead of keeping the existing Markers rendered.
Expected result
Children should be able to be resorted without subview re-render.
Actual result
Subviews are re-rendered.
React Native Maps Version
1.13.0
What platforms are you seeing the problem on?
iOS (Apple Maps)
React Native Version
0.73.4
What version of Expo are you using?
SDK 50
Device(s)
iPhone 15 Pro (17.3.1)
Additional information
No response
The text was updated successfully, but these errors were encountered:
@night@Neiso I was actually curious to analyze this bug and it took me too long to figure out what's going on.
Long story short is that this is not a bug per say, rather an expectation of a feature that we don't have.
specifically react-native does not support shuffling of children in a parent container without re-rendering the subviews, the DOM tree changes with the reshuffling and that triggers a re-render, you can easily test that by creating a custom react-native view and add some child views to it and shuffle them, you will see insertReactSubview and removeReactSubview being called.
I then looked into FlatList Implementation to find out that there is handling via keyExtractor to practically keep children ordered regardless of the input based on key, that way the list doesn't refresh content when they're shuffled, at least that's my current understanding.
but to get back to the problem you have, please look into @yanksyoon idea, or even better try to use Memorize it works well for blocking re-renders.
so this won't be considered as a bug, but feel free to add a suggestion for a new feature that makes it possible for MapView to keep track of markers by ID. here is the discussion we have for the roadmap: #4975
Summary
When using react-native-maps with dynamic/changing
Marker
children arrays, memoization appears not enough to prevent render flicker.I suspect from reading the native source code that this may be caused by annotations being added and removed on the native side, instead of preserving existing annotations added. More specifically, I think on the native side you may be receiving
insertReactSubview
andremoveReactSubview
when indexes change for a subview, even when that subview's reference is not changing.After trying to debug and work around this issue, I found that explicitly passing an array of children at fixed indices, I can add and remove children without seeing subview flicker.
Ref: #5014
Reproducible sample code
RPReplay_Final1711993263.MP4
Steps to reproduce
Load the sample code provided. Notice that the library re-renders Markers with a flicker instead of keeping the existing Markers rendered.
Expected result
Children should be able to be resorted without subview re-render.
Actual result
Subviews are re-rendered.
React Native Maps Version
1.13.0
What platforms are you seeing the problem on?
iOS (Apple Maps)
React Native Version
0.73.4
What version of Expo are you using?
SDK 50
Device(s)
iPhone 15 Pro (17.3.1)
Additional information
No response
The text was updated successfully, but these errors were encountered: