I add react native maps in expo but its working so slowly, really now I don’t know what I can do. Any suggestion? Also I have a issue in map marker I add my custom marker but its blinking, I put trackVieChanges false with some condition because without that images are not showing.
CustomMapComponent
import React, {useMemo, useEffect, useCallback} from "react";
import {View, StyleSheet} from "react-native";
import MapView, {PROVIDER_GOOGLE} from "react-native-maps";
import CustomMarker from "./MapMarker/CustomMarker";
import {aubergine} from "./mapStyles/aubergine";
import {useAppDispatch, useAppSelector} from "../../hook/reduxHooks";
import {DARK} from "../../store/reducer/types";
import {standard} from "./mapStyles/standard";
import BottomSheetFilters from "../ButtomSheetFilters/ButtomSheetFilters";
import {FilterService} from "../../services/FilterService/FilterService";
import {uniqForMapMarker} from "../../helpers/helper";
import {setSubFilteredEvents} from "../../store/reducer/event/eventReducer";
import {setFilters, setUnselectedFilters} from "../../store/reducer/filter/filterReducer";
const lat1 = 40.15839363088361;
const lng1 = 44.401019811630256;
const lat2 = 40.18831582616864;
const lng2 = 44.52758789062501;
const latitudeDelta = Math.abs(lat2 - lat1) * 1.25; // Add some padding
const longitudeDelta = Math.abs(lng2 - lng1) * 1.2; // Add some padding
const centerLat = (lat1 + lat2) / 2;
const centerLng = (lng1 + lng2) / 2;
const initialRegion = {
latitude: centerLat,
longitude: centerLng,
latitudeDelta,
longitudeDelta,
};
export type locationType = { latitude: number; longitude: number } | null;
export default function CustomMap() {
const dispatch = useAppDispatch();
const {
theme: colors,
filters: {selectedFilters, bottomFilter, topFilter},
events: {events}
} = useAppSelector(state => state);
// Filter events based on top filter
const topFilteredEvents = useMemo(() => {
return FilterService.topFilter(events, topFilter);
}, [topFilter, events]);
// Get bottom filtered events and dispatch filter updates
const {eventLists, filters} = useMemo(() => {
return FilterService.bottomFilteredEvents(topFilteredEvents, bottomFilter);
}, [topFilteredEvents, bottomFilter]);
useEffect(() => {
dispatch(setFilters(filters));
dispatch(setUnselectedFilters({
filters,
filterType: 'updateAll'
}));
}, [dispatch, filters]);
const subFilteredEvents = useMemo(() => {
const events = FilterService.subFilter(eventLists, selectedFilters);
const eventsUniq = uniqForMapMarker(events);
dispatch(setSubFilteredEvents(eventsUniq));
return eventsUniq;
}, [eventLists, selectedFilters, dispatch]);
const renderMarkers = useCallback(() => {
return subFilteredEvents.map((event, index) => (
<CustomMarker key={index} {...event} />
));
}, [subFilteredEvents]);
return (
<View style={mapStyle.container}>
<MapView
{...{
minZoomLevel: 10,
key: `MAP_KEY_25`,
showsScale: false,
style: mapStyle.map,
showsTraffic: false,
showsCompass: false,
showsIndoors: false,
toolbarEnabled: false,
moveOnMarkerPress: false,
provider: PROVIDER_GOOGLE,
initialRegion: initialRegion,
showsIndoorLevelPicker: false,
mapPadding: {top: 20, right: 20, bottom: 100, left: 20},
customMapStyle: colors.mode === DARK ? aubergine : standard
}}
loadingEnabled
showsUserLocation
showsMyLocationButton
>
{renderMarkers()}
</MapView>
<BottomSheetFilters/>
</View>
);
}
const mapStyle = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
justifyContent: "flex-start",
alignItems: "center",
},
map: {
...StyleSheet.absoluteFillObject,
},
});
here is my custom marker compoment
import React, {useEffect, useState} from "react";
import {StyleSheet, View, Text} from "react-native";
import {Image} from "expo-image";
import {Marker, Callout} from "react-native-maps";
import {useNavigation} from "@react-navigation/native";
import {useAppDispatch} from "../../../hook/reduxHooks";
import {IEventCart} from "../../../types/event.type";
import MiniProfile from "../../MiniProfile/MiniProfile";
import {setUser} from "../../../store/reducer/user/user";
import {isBetweenDates} from "../../../helpers/helper";
import {useTranslatedRoutes} from "../../../hook/translatedRoutes";
import image from "../../../../assets/images";
interface ICustomMarkerProps extends IEventCart {
}
export default React.memo(function CustomMarker(props: ICustomMarkerProps) {
const {user, startDate, endDate} = props;
const {location: {lat: latitude, lng: longitude}, avatar} = user;
const dispatch = useAppDispatch();
const navigate = useNavigation();
const routes = useTranslatedRoutes();
const [imageLoaded, setImageLoaded] = useState(false);
const [avatarLoaded, setAvatarLoaded] = useState(false);
useEffect(() => {
return () => {
setImageLoaded(() => false);
setAvatarLoaded(() => false)
}
})
const handlePressCallout = () => {
dispatch(setUser(user));
navigate.navigate(routes.partnerProfile.key as never);
};
return (
<Marker
coordinate={{latitude: +latitude, longitude: +longitude}}
key={`${latitude}-${longitude}`} // Ensuring unique key
tracksViewChanges={!imageLoaded && !avatarLoaded} // Track view changes based on image loading
>{isBetweenDates(startDate, endDate) && (
<View style={customMapStyle.liveContainer}>
<Text style={customMapStyle.liveText}>Live</Text>
</View>
)}
<Image
source={image.marker_icon}
style={customMapStyle.markerIcon}
onLoad={() => setImageLoaded(true)} // Set image loaded state
/>
<View style={customMapStyle.avatarContainer}>{/* Added wrapper View for avatar */}
<Image
source={{uri: avatar}}
style={customMapStyle.partnerLogo}
onLoad={() => setAvatarLoaded(true)} // Set avatar loaded state
/>
</View>
<Callout
tooltip
style={customMapStyle.calloutContainer}
onPress={handlePressCallout}
><MiniProfile user={user}/>
</Callout>
</Marker>
);
}, (prevProps, nextProps) => {
const {user: {location: prevLocation}} = prevProps;
const {user: {location: nextLocation}} = nextProps;
return nextLocation.lat !== prevLocation.lat && nextLocation.lng !== prevLocation.lng;
})
const customMapStyle = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
justifyContent: "flex-end",
alignItems: "center",
},
liveContainer: {
width: 30,
height: 15,
left: 6.5,
backgroundColor: "#e9b408",
display: "flex",
justifyContent: "center",
alignItems: "center",
borderRadius: 12,
},
liveText: {
fontSize: 8,
fontWeight: "700",
color: "red",
},
lottieIcon: {
width: 45,
height: 45,
},
lottieAvatar: {
borderRadius: 1000,
width: 22,
height: 22,
left: 11,
bottom: 40,
},
iconContainer: {
padding: 0,
},
avatarContainer: { // Added style for avatar wrapper
borderRadius: 1000,
overflow: "hidden",
width: 26,
height: 26,
left: 5,
bottom: 33,
},
partnerLogo: {
width: "100%",
height: "100%",
},
markerIcon: {
width: 36,
height: 36,
},
map: {
...StyleSheet.absoluteFillObject,
},
calloutContainer: {
borderRadius: 5,
},
calloutText: {
fontWeight: "bold",
},
});
Pls help me to resolve mt problem thanks a lot
I am trying fix react native expo map part performance and map marker blinking