Итак, есть несколько проблем в том, как вы настроили его с точки зрения логики c. Я считаю, что я исправил все проблемы, которые я видел в вашем коде ниже.
Причина, по которой печатался только 0, заключается в том, что у currentLatitude / currentLongitude / currentTimestamp, на который ссылалась функция getLocation, было закрытие вокруг после запуска интервала не будет sh обновляться до новой версии функции, которая создавалась при каждом повторном рендеринге. Чтобы устранить это, я удалил ссылки на эти переменные из функции getLocation в сделанных мною изменениях.
Причина, по которой все еще выводились 0, заключается в том, что для getLocationInterval было установлено значение undefined в каждом рендере. Вам бы пришлось сделать это либо ссылкой, либо переменной состояния, чтобы это оставалось между повторными рендерингами.
Я переместил logi c из функции startStop в хук useEffect, так как это правильный способ добиться эффекта изнутри компонента крючка. Это также позволяет объединить все логи c в одном прямом месте, которое можно легко извлечь в пользовательский хук, если вам нужно использовать его в других местах.
const Tracking = props => {
const [currentLatitude, setCurrentLatitude] = useState(0);
const [currentLongitude, setCurrentLongitude] = useState(0);
const [currentTimestamp, setCurrentTimestamp] = useState(0);
const [isTracking, setIsTracking] = useState(false);
useEffect(() => {
if (!isTracking) return;
function getLocation() {
navigator.geolocation.getCurrentPosition(
position => {
setCurrentLongitude(position.coords.longitude);
setCurrentLatitude(position.coords.latitude);
setCurrentTimestamp(position.timestamp);
console.log(
position.coords.longitude,
position.coords.latitude,
position.timestamp
);
},
error => alert(error.message),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
let getLocationInterval = setInterval(getLocation, 500);
return () => clearInterval(getLocationInterval);
}, [isTracking]);
return (
<View style={{ width: '100%', height: '100%' }}>
<MapView showsUserLocation style={{ flex: 1 }} />
<MenuButton
title={isTracking ? 'Stop' : 'Start'}
onPress={() => {
setIsTracking(!isTracking);
}}
/>
</View>
);
};
Редактировать: Объяснение return from useEffect:
Функция возврата в строке 27 приведенного выше кода: return () => clearInterval(getLocationInterval);
clearInterval запускается не сразу, поскольку является частью объявления функции стрелки. Мы возвращаем эту функцию, а не вызываем ее напрямую. После того, как мы вернем объявление функции, activ теперь снова контролирует код и вызывает его, когда захочет.
В частности, useEffect
позволяет вам вернуть функцию, которая используется для очистки. И он вызывает эту функцию для компонента, размонтирующего или непосредственно перед тем, как он снова запускает ловушку (т. Е. Массив зависимостей изменился)
В официальной документации реагирования есть немного больше информации: https://reactjs.org/docs/hooks-reference.html#cleaning -up-an -эффект