First of all, I apologize if I don't post correctly, due to it's my first post ever in Stack Overflow.
Well, why am I here? I'm a software engineer and it's my first time working with react-native and I'm making an app that tracks the user by GPS, getting the speed and the traveled distance, however I'm desperate because I can't get the speed nor the distance traveled.
My code starts with a button to "start journey", which sets isTracking=true. and if you end the journey it sets isTracking=false. When isTracking=true, it gets the speed and traveled distance. Speed should be visible at all times.
I think i have a mess between many components and getting calls to user's location.
so well, this is my main component:
import React, { useState, useEffect } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import MapComponent from './MapComponent';
import DistanceComponent from './DistanceComponent';
import * as Location from 'expo-location';
import { GOOGLE_MAPS_KEY } from '@env';
import TimeComponent from './TimeComponent';
import LocationSearchComponent from './LocationSearchComponent';
import VehiculoChooser from './VehiculoChooser';
import ButtonIniciarViaje from './ButtonIniciarViaje';
import TotalRouteCost from './TotalRouteCost';
import { useNavigation } from '@react-navigation/native';
import TimeComponentLive from './TimeComponentLive';
import DistanceComponentLive from './DistanceComponentLive';
import SpeedComponentLive from './SpeedComponentLive';
import TotalRouteCostLive from './TotalRouteCostLive';
const GPSDestination = ({ sucursal }) => {
const [origin, setOrigin] = useState(null);
const [destination, setDestination] = useState(null);
const [distance, setDistance] = useState(null);
const [time, setTime] = useState(null);
const [initialLocation, setInitialLocation] = useState(null);
const [vehiculoSeleccionado, setVehiculoSeleccionado] = useState(null);
const [isTracking, setIsTracking] = useState(false);
const navigation = useNavigation();
const [mapRegion, setMapRegion] = useState(null);
const [originMarkerColor, setOriginMarkerColor] = useState('red');
const [elapsedTime, setElapsedTime] = useState(0);
const [distanceTraveled, setDistanceTraveled] = useState(0);
const [speed, setSpeed] = useState(0);
const [previousLocation, setPreviousLocation] = useState(null);
const [updateTimer, setUpdateTimer] = useState(null);
const [costLive, setCostLive] = useState(null);
const [locationSubscription, setLocationSubscription] = useState(null);
const geolib = require('geolib');
const [routeDetails, setRouteDetails] = useState({
distance: null,
duration: null,
tolls: [],
});
const MIN_DISTANCE_UPDATE = 10;
const UPDATE_INTERVAL = 5000;
const MIN_SPEED_THRESHOLD = 0.27778;
const handleStartTracking = async () => {
console.log('Tracking started');
setIsTracking(true);
setInitialLocation(null); // Reiniciar la ubicación inicial al iniciar el rastreo
setDistanceTraveled(0); // Restablecer la distancia cuando se inicia el rastreo
};
const handleStopTracking = () => {
console.log('Tracking stopped');
setIsTracking(false);
setUpdateTimer(null);
// Verifica si locationSubscription está definido antes de intentar limpiarlo
if (locationSubscription && locationSubscription.remove) {
console.log('Removing location subscription');
locationSubscription.remove();
}
};
useEffect(() => {
console.log("Console log 0");
const getLocationOnAppStart = async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
console.error('Permission to access location was denied');
return;
}
const location = await Location.getCurrentPositionAsync({});
setOrigin(location.coords);
setPreviousLocation(location.coords); // Establecer la ubicación inicial como la anterior
};
getLocationOnAppStart();
}, []);
useEffect(() => {
console.log("Console log 1");
let intervalId;
if (isTracking) {
intervalId = startTimer();
} else {
clearInterval(intervalId);
}
return () => clearInterval(intervalId); // Limpiar el temporizador correctamente
}, [isTracking]);
useEffect(() => {
console.log("Console log 1.5");
if (isTracking) {
setDistanceTraveled(0); // Establecer la distancia a cero cuando isTracking cambie a true
}
}, [isTracking]);
useEffect(() => {
console.log("Console log 2");
console.log('Requesting location permission...');
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
console.log('Permission to access location was denied');
return;
}
})();
}, []);
useEffect(() => {
console.log("Console log 3");
let subscription = null; // Inicializa la variable de suscripción
const startLocationUpdates = async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
console.error('Permission to access location was denied');
return;
}
const locationOptions = {
accuracy: Location.Accuracy.BestForNavigation,
timeInterval: 1000,
};
subscription = await Location.watchPositionAsync(locationOptions, (location) => {
console.log('New location:', location.coords);
console.log('Speed:', location.coords.speed); // Agregar console log de la velocidad
if (!origin) {
console.log('Setting initial origin:', location.coords);
setOrigin(location.coords);
setPreviousLocation(location.coords);
} else if (isTracking && location.coords.speed > MIN_SPEED_THRESHOLD) { // Añadir condición de velocidad mínima
const distance = calculateDistance(previousLocation, location.coords);
console.log('Calculated distance:', distance);
setDistanceTraveled(prevDistance => prevDistance + distance);
setPreviousLocation(location.coords);
if (distance >= MIN_DISTANCE_UPDATE && !updateTimer) {
setUpdateTimer(setTimeout(() => {
setUpdateTimer(null);
}, UPDATE_INTERVAL));
}
}
});
};
if (isTracking) {
startLocationUpdates();
} else {
// Detener la suscripción si se detiene el rastreo
if (subscription) {
console.log('Removing location subscription');
subscription.remove();
}
if (updateTimer) {
clearTimeout(updateTimer);
setUpdateTimer(null);
}
}
return () => {
// Limpiar las suscripciones y los temporizadores al desmontar el componente
if (subscription) {
console.log('Removing location subscription');
subscription.remove();
}
if (updateTimer) {
clearTimeout(updateTimer);
setUpdateTimer(null);
}
};
}, [isTracking, origin, previousLocation, updateTimer]);
const calculateDistance = (previousCoords, currentCoords) => {
if (!previousCoords || !currentCoords ||
!previousCoords.latitude || !previousCoords.longitude ||
!currentCoords.latitude || !currentCoords.longitude) {
console.log('One or both coordinates are invalid:', { previousCoords, currentCoords });
return 0;
}
try {
const distanceTraveled = geolib.getDistance(
{ latitude: previousCoords.latitude, longitude: previousCoords.longitude },
{ latitude: currentCoords.latitude, longitude: currentCoords.longitude }
);
return distanceTraveled;
} catch (error) {
console.error('Error calculating distance:', error);
return 0;
}
};
const startTimer = () => {
return setInterval(() => {
setElapsedTime(prevTime => prevTime + 1); // Incrementa el tiempo transcurrido en 1 segundo
}, 1000); // Llama a la función cada segundo
};
const stopTimer = (intervalId) => {
clearInterval(intervalId);
};
const fetchDetails = async (placeId) => {
try {
const resp = await fetch(`https://maps.googleapis.com/maps/api/place/details/json?place_id=${placeId}&key=${GOOGLE_MAPS_KEY}`);
const data = await resp.json();
return data.result;
} catch (error) {
console.error('Error fetching location details:', error);
return null;
}
};
const handleSelectVehiculo = (vehiculo) => {
setVehiculoSeleccionado(vehiculo);
};
useEffect(() => {
console.log("Console log 4");
console.log('Requesting location permission...');
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
console.log('Permission to access location was denied');
return;
}
let currentLocation = await Location.getCurrentPositionAsync({});
setOrigin(currentLocation.coords);
})();
}, []);
useEffect(() => {
console.log("Console log 5");
if (origin && destination) {
calculateDistance();
}
}, [origin, destination, vehiculoSeleccionado]);
useEffect(() => {
//busca informacion con fetch cuando origin y destination están disponibles en el mapa
console.log("Console log 5.5");
if (origin && destination) {
fetchRouteDetails();
}
}, [origin, destination]);
const fetchRouteDetails = async () => {
try {
const response = await fetch(
`https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude},${origin.longitude}&destination=${destination.latitude},${destination.longitude}&key=${GOOGLE_MAPS_KEY}`
);
const data = await response.json();
if (data.status === 'OK') {
const totalDistance = data.routes[0].legs[0].distance.text;
const totalDuration = data.routes[0].legs[0].duration.text;
const tollsInfo = data.routes[0].legs[0].steps.filter(step => step.toll);
setRouteDetails({
distance: totalDistance,
duration: totalDuration,
tolls: tollsInfo,
});
}
} catch (error) {
console.error('Error fetching directions:', error);
}
};
const onSelectDestination = (coords) => {
setDestination(coords);
};
const handleLocationChange = (location) => {
const calculatedSpeed = location.coords.speed;
if (calculatedSpeed !== null && !isNaN(calculatedSpeed)) {
setSpeed(calculatedSpeed);
} else {
setSpeed(0);
}
setPreviousLocation(location.coords);
};
const handleVehiculoSeleccionado = (vehiculo) => {
setVehiculoSeleccionado(vehiculo);
};
const onMapLayout = () => {
// Implementa tu lógica para el diseño del mapa si es necesario
};
return (
<View>
<LocationSearchComponent
key="LocationSearchComponent"
onSelectLocation={onSelectDestination}
fetchDetails={fetchDetails}
/>
<MapComponent
key="MapComponent"
origin={origin}
destination={destination}
onLocationChange={handleLocationChange}
setOrigin={setOrigin}
setDestination={setDestination}
onMapLayout={onMapLayout}
initialRegion={mapRegion}
onStartTracking={handleStartTracking}
isTracking={isTracking}
setOriginMarkerColor={setOriginMarkerColor}
tolls={routeDetails.tolls} // Pasa los detalles de la ruta como prop
/>
<Text style={[styles.title, styles.bottomBorder]}>Datos estimados</Text>
<View style={styles.containerData}>
<TimeComponent key="TimeComponent" time={routeDetails.duration || ''} />
<DistanceComponent key="DistanceComponent" distance={routeDetails.distance} />
<TotalRouteCost key="TotalRouteCost" sucursal={sucursal} distance={routeDetails.distance} time={routeDetails.duration} vehiculoSeleccionado={vehiculoSeleccionado} />
</View>
<Text style={[styles.title, styles.bottomBorder]}>Datos en tiempo real</Text>
<View style={styles.containerData}>
{isTracking && <TimeComponentLive time={elapsedTime} />}
{isTracking && <DistanceComponentLive distanceTraveled={distanceTraveled} />}
<SpeedComponentLive speed={speed} />
{isTracking && <TotalRouteCostLive distanceTraveled={distanceTraveled} elapsedTime={elapsedTime} sucursal={sucursal} vehiculoSeleccionado={vehiculoSeleccionado} />}
</View>
<VehiculoChooser onSelectVehiculo={handleSelectVehiculo} />
<View style={styles.containerButtons}>
{origin && destination && (
<ButtonIniciarViaje onPress={isTracking ? handleStopTracking : handleStartTracking} isTracking={isTracking} />
)}
</View>
</View>
);
};
const styles = StyleSheet.create({
containerData: {
marginTop: 10,
flexDirection: 'row',
justifyContent: 'center',
},
containerButtons: {
display: 'flex',
flexDirection: 'column',
marginTop: 10,
alignItems: 'center',
gap: 5,
},
bottomBorder: {
textAlign: 'center',
width: '90%',
borderBottomWidth: 0.8,
borderBottomColor: 'grey',
alignSelf: 'center',
},
title: {
marginTop: 10,
textAlign: 'center',
fontSize: 16,
fontWeight: 'bold',
marginBottom: 0,
},
});
export default GPSDestination;
I really hope you guys can help me, i'm having a lot of trouble with this.
Also, this is an error I keep getting:
ERROR Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
Please I need some guidance, I'm sure my code is a mess, and it grew so much that I can't find the problem!
Also, this is some log I get:
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31685561664034, "longitude": -73.01744943150514, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 19
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31685561664034, "longitude": -73.01744943150514, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 19
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31685561664034, "longitude": -73.01744943150514, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 19
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31685561664034, "longitude": -73.01744943150514, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 19
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.3168627365243, "longitude": -73.01743782653836, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 21
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.3168627365243, "longitude": -73.01743782653836, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 20
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.3168627365243, "longitude": -73.01743782653836, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 21
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.3168627365243, "longitude": -73.01743782653836, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 20
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.3168627365243, "longitude": -73.01743782653836, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 21
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.3168627365243, "longitude": -73.01743782653836, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 20
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
ERROR Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.316869943218485, "longitude": -73.01742608007632, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 22
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31687709468896, "longitude": -73.01741442362548, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 23
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31687709468896, "longitude": -73.01741442362548, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 23
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31687709468896, "longitude": -73.01741442362548, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 23
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31687709468896, "longitude": -73.01741442362548, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 23
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31688432508056, "longitude": -73.01740263853813, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 24
LOG Console log 3
LOG Console log 3
LOG Console log 3
LOG New location: {"accuracy": 3.9000000953674316, "altitude": 0, "altitudeAccuracy": 0, "heading": 129.13783264160156, "latitude": -41.31688432508056, "longitude": -73.01740263853813, "speed": 1.3888888359069824}
LOG Speed: 1.3888888359069824
LOG Calculated distance: 24
LOG Console log 3
LOG Console log 3
thank you very much guys, I hope you can enlighten me!
I tried moving the code that calculates speed and distance traveled to their own components but I made it worse