I update the map view by scrolling, which fires the handleRegionChange
callback.
For some reason, if I don't add if (!data.length) return null
, first render won't render the markers (understandable because there's no data yet). When the data does resolve, it doesn't trigger a rerender of the markers. If I scroll on the map it also crashes Expo
Unfortunately, if I add this, the whole map rerenders every time I want to I get quite a janky experience with the MapMarkers rendering on the map, and the whole map rerenders.
I think I'm missing something, but not quite sure what it is. I've tried creating a <MapMarkers mapViewRegion={mapViewRegion} />
component where the data fetching is isolated to the MapMarkers, to no avail.
function MapViewWithMarkers({ location }: { location: LocationObject }) {
const mapRef = useRef<MapView>(null);
const [mapViewRegion, setMapViewRegion] = useState<Region>({
latitude: location.coords.latitude,
longitude: location.coords.longitude,
latitudeDelta: 0.015,
longitudeDelta: 0.015,
});
const handleRegionChange = (region: Region) => {
setMapViewRegion(region);
};
const { data, isLoading } = trpc.venues.useQuery({ lat: mapViewRegion.latitude, lon: mapViewRegion.longitude, limit: 10 });
// if (!data?.length) return null;
return (
<View style={{ flex: 1 }}>
<MapView
ref={mapRef}
showsUserLocation={true}
region={mapViewRegion}
showsPointsOfInterest={false}
onRegionChangeComplete={handleRegionChange}
style={{ width: "100%", height: "100%", flex: 1 }}
loadingEnabled={true}
showsMyLocationButton={true}
>
{data?.map((venue) => (
<MapMarker
key={venue.id}
identifier={venue.id.toString()}
coordinate={{ latitude: Number(venue.latitude), longitude: Number(venue.longitude) }}
title={venue.name}
description={`${venue.address}`}
/>
))}
</MapView>
</View>
);
}