I need to load a map in a component, with a loading circle appearing while the component is loading the user location. The thing is, it works, too well indeed. What I mean, if I don't have a location (maybe because I didnt gave permission to) the loading circle appears for ever, or until a location is given.
How can I set this loading component to be in a while and after it, justo load a given coordinates?
loading component
import React from 'react';
import { CustomView as View } from '../View/View';
import { StyleSheet } from 'react-native';
import { ActivityIndicator } from 'react-native';
export const Loading = ({size, color}) => {
return(
<View style={styles.viewLoading}>
<ActivityIndicator size={size} color={color} />
</View>
)
}
const styles = StyleSheet.create({
viewLoading: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
and this is my map component
import React, { useState, useEffect } from "react";
import { StyleSheet, Image } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import MapView, { Marker, Callout } from 'react-native-maps';
import { Loading } from 'components/elements';
import * as Location from 'expo-location';
import { View, Text } from "components/elements";
import colors from "components/elements/colors";
const Map = (props) => {
const {
onCalloutPress,
franchises,
} = props;
const [userLocation, setUserLocation] = useState(null);
const [region, setRegion] = useState(null);
const [selectedLocal, setSelectedLocal] = useState()
const [loading, setLoading] = useState(true)
useEffect(() => {
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
return;
}
let location = await Location.getCurrentPositionAsync({});
{
setUserLocation(location) !== null
?
isLoading(false)
: {}
}
setRegion({
latitude: location?.coords?.latitude,
longitude: location?.coords?.longitude,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
})
})();
}, []);
const isLoading = (boolean) => {
setLoading(boolean)
}
if (!(region || franchises.length)) return null;
const handleSelectLocal = (franchises) => {
onCalloutPress(franchises)
setSelectedLocal(franchises)
}
return (
<>
{/* TODO MAP APPEAR WHEN NO LOCATION IS FOUND AFTER A WHILE */}
{!loading
?
<MapView
style={styles.map}
zoomControlEnabled={true}
initialRegion={region}
>
{userLocation &&
< Marker
coordinate={userLocation.coords}
>
<Image
source={require("components/elements/assets/Imagen_perfil.png")}
style={{ width: 35, height: 35 }}
/>
</Marker>
}
{
franchises.map((stop, i) => (
<Marker
coordinate={{ latitude: Number(stop.latitude), longitude: Number(stop.longitude) }}
key={i}
onPress={() => setSelectedLocal(stop)}
>
{selectedLocal?.latitude === stop.latitude && selectedLocal?.longitude === stop.longitude ?
<Image
source={require("../../elements/assets/MapPin.png")}
style={{ width: 41 }}
/> :
<Image
source={require("components/elements/assets/yellowIcon.png")}
style={{ width: 41, height: 41 }}
/>
}
<Callout
tooltip
onPress={e => handleSelectLocal(stop)}
>
<View style={styles.calloutView}>
<Text style={styles.calloutName}>{stop.Nombre}</Text>
<Text style={styles.calloutAddress}><Ionicons name="location-outline" size={15} color="black" /> {stop.Direccion}</Text>
</View>
</Callout>
</Marker>
))
}
</MapView >
: <Loading size="large" color="#F5BF0D" style={ styles.loading}/>
}
</>
);
};
const styles = StyleSheet.create({
map: {
flex: 1
},
loading:{
display:"flex",
alignContent:"center",
alignItems:"center"
},
calloutView: {
backgroundColor: colors.accent,
paddingHorizontal: 15,
paddingVertical: 11,
width: 200,
borderRadius: 5,
marginBottom: 10,
},
calloutName: {
fontFamily: 'Montserrat_700Bold',
fontSize: 15
},
calloutAddress: {
fontFamily: 'Montserrat_400Regular',
fontSize: 15
}
});
export default Map;
``