In the code below, when the app loads initially "Location changed offline!" is logged every time the location updates. When online
is set to true with a TouchableOpacity, the message logged to the console looks like this:
LOG true
LOG attempting to update location...
LOG Location updated in real-time!
LOG false
LOG Location changed offline!
LOG true
LOG attempting to update location...
LOG true
LOG attempting to update location...
LOG Location updated in real-time!
For some reason it's randomly changing the state of online
back to false, thus causing the "Location changed offline!" to be logged. What could be causing this?
const [online, setOnline] = useState(false);
useEffect(() => {
Geolocation.watchPosition(
position => {
console.log(online);
if (online) {
console.log('attempting to update location...');
const payload = {
lat: position.coords.latitude,
lng: position.coords.longitude,
id: 1,
};
axios
.post('http://localhost:3000/location/update', payload)
.then(res => {
if (res.status === 200) {
console.log('Location updated in real-time!');
return;
}
})
.catch(err => console.log(err.response));
} else {
console.log('Location changed offline!');
}
},
err => console.log(err.response)
);
}, [online]);
CodePudding user response:
The problem here is that you add a new watcher every time online
changes that captures the current value forever.
Adding subscriptions (like Geolocation.watchPosition()
) within an effect hook should always be removed in the cleanup function.
useEffect(() => {
const watchId = Geolocation.watchPosition(async (position) => {
console.log("online?", online);
if (online) {
console.log("attempting to update location...");
const payload = {
lat: position.coords.latitude,
lng: position.coords.longitude,
id: 1,
};
try {
await axios.post("http://localhost:3000/location/update", payload);
// no need to check the response status
console.log("Location updated in real-time!");
} catch (err) {
console.warn(err.toJSON()); // Axios helper, much nicer to look at
}
} else {
console.log("Location changed offline!");
}
}, console.error);
// return a cleanup function
return () => {
Geolocation.clearWatch(watchId);
};
}, [online]);
See https://reactnative.dev/docs/0.63/geolocation#clearwatch