Mapbox Implementation
Mapbox
Mapbox Version
11.15.3
React Native Version
0.81.4
React Native Architecture
New Architecture (Fabric/TurboModules)
Platform
Android
@rnmapbox/maps version
10.2.5
Standalone component to reproduce
// BugReportExampleSymbols.js (pure JS)
import React, {useCallback, useMemo, useState} from 'react';
import {
MapView,
ShapeSource,
SymbolLayer,
Camera,
Images,
} from '@rnmapbox/maps';
import {View, Button, StyleSheet} from 'react-native';
// If needed in your app entry, remember to set your token:
// import Mapbox from '@rnmapbox/maps';
// Mapbox.setAccessToken('YOUR_TOKEN');
const CENTER = [-74.00597, 40.71427];
const PIN_URL =
'https://raw.githubusercontent.com/rnmapbox/maps/refs/heads/main/example/src/assets/pin.png';
const EMPTY_FC = {
type: 'FeatureCollection',
features: [],
};
const layerStyle = {
iconImage: ['get', 'icon'], // read image id from feature properties.icon
iconAllowOverlap: true,
iconIgnorePlacement: true,
iconSize: 0.7,
};
function makeRandomPoints(count, around) {
const [lng, lat] = around;
const features = [];
for (let i = 0; i < count; i++) {
// small jitter around center
const dx = (Math.random() - 0.5) * 0.01;
const dy = (Math.random() - 0.5) * 0.01;
features.push({
type: 'Feature',
id: `pt-${i}`,
properties: {
icon: `pin-${i}`, // unique image id per point
},
geometry: {
type: 'Point',
coordinates: [lng + dx, lat + dy],
},
});
}
return {type: 'FeatureCollection', features};
}
export default function BugReportExampleSymbols() {
const [fc, setFc] = useState(EMPTY_FC);
const [imgs, setImgs] = useState({});
const loadPointsAndImages = useCallback(() => {
// 1) Prepare 10 unique image IDs (all backed by the SAME URL)
const nextImgs = {};
for (let i = 0; i < 10; i++) {
// cache-bust query so RN treats them as distinct if needed
nextImgs[`pin-${i}`] = {uri: `${PIN_URL}?v=${i}`};
}
setImgs(nextImgs);
// 2) Create 10 point features that reference the above image ids
setFc(makeRandomPoints(10, CENTER));
}, []);
const clearAll = useCallback(() => {
setImgs({});
setFc(EMPTY_FC);
}, []);
const camera = useMemo(
() => <Camera centerCoordinate={CENTER} zoomLevel={14} />,
[],
);
return (
<View style={styles.container}>
<View style={styles.row}>
<Button title="Load 10 points + images" onPress={loadPointsAndImages} />
<View style={styles.spacer} />
<Button title="Clear" onPress={clearAll} />
</View>
<MapView style={styles.map}>
{camera}
{/* Provide images so SymbolLayer can resolve icon ids */}
<Images images={imgs} />
<ShapeSource id="bug-symbol-source" shape={fc}>
<SymbolLayer id="bug-symbol-layer" style={layerStyle} />
</ShapeSource>
</MapView>
</View>
);
}
const styles = StyleSheet.create({
container: {flex: 1},
row: {
flexDirection: 'row',
padding: 8,
gap: 8,
backgroundColor: '#ffffff',
zIndex: 1,
},
spacer: {width: 8},
map: {flex: 1},
});
Observed behavior and steps to reproduce
The images are resolved to a URI and set on the <images> component. But the images are never rendered to the screen or if they are only 1 or two is.
To reproduce, just run the code and then click the button to load the pins.
Expected behavior
It should render the pins on the map.
Notes / preliminary analysis
It appears to be a race condition of some sort because if i pause the code after react starts processing the set images it will render them all.
Additional links and references
No response
Mapbox Implementation
Mapbox
Mapbox Version
11.15.3
React Native Version
0.81.4
React Native Architecture
New Architecture (Fabric/TurboModules)
Platform
Android
@rnmapbox/mapsversion10.2.5
Standalone component to reproduce
Observed behavior and steps to reproduce
The images are resolved to a URI and set on the
<images>component. But the images are never rendered to the screen or if they are only 1 or two is.To reproduce, just run the code and then click the button to load the pins.
Expected behavior
It should render the pins on the map.
Notes / preliminary analysis
It appears to be a race condition of some sort because if i pause the code after react starts processing the set images it will render them all.
Additional links and references
No response