React Native GeoLocation.watchPosition() 在成功回调中使用状态的初始值
React Native GeoLocation.watchPosition() using Initial value of state in success callback
我正在制作一个“寻宝”小径应用程序。用户可以去一个位置,当他们到达那个位置时,一个动作就会发生。为了监控用户位置,我使用来自“react-native-geolocation-service”的 Gelocation.watchposition()。
兴趣点 (trailLocation) 是从我们的 API 中获取的,我用它设置了“trailLocation”状态,它正确更新并且一切看起来都不错。 (initialTrailLocation passed from previous screen)
const [trailLocation, setTrailLocation] = useState(initialTrailLocation);
/**
* Function to get the next trail location
*/
let getNextLocation = async () => {
setIsLoading(true);
const credentials = await Keychain.getGenericPassword();
await axios.get(BACKEND_URL + 'api/v1/trails/' + trail.id + '/user/' + credentials.username + '/next-location?include=trail_location_ar_object.ar_object.ar_object_resources', {
headers: {
Authorization: 'Bearer ' + credentials.password,
},
},
)
.then(response => {
setTrailLocation(response.data.data.trail_location);
setIsLoading(false);
setUserWithinRange(false);
})
.catch(error => {
console.log(error);
});
};
/**
* Function called when the position changes
*/
function newPositionHandler(data) {
console.log("new position handler");
let radius = 1000;
let ky = 40000 / 360;
console.log(trailLocation);
let kx = Math.cos((Math.PI * trailLocation.lat) / 180.0) * ky;
let dx = Math.abs(trailLocation.lon - data.coords.longitude) * kx;
let dy = Math.abs(trailLocation.lat - data.coords.latitude) * ky;
setDistance(Math.sqrt(dx * dx + dy * dy));
console.log(Math.sqrt(dx * dx + dy * dy));
console.log('-------------------');
if(Math.sqrt(dx * dx + dy * dy) <= radius / 1000) {
setUserWithinRange(true);
} else {
setUserWithinRange(false)
}
};
/** Function called to initialise the watch position functionality */
async function watchPosition() {
console.log("watch position");
Geolocation.watchPosition((data) => newPositionHandler(data), (error) => console.log(error),{
enableHighAccuracy: false,
timeout: 10000,
maximumAge: 1000,
distanceFilter: 5,
},
);
};
但是,当 watchposition 的成功函数被触发时,它使用“trailLocation”状态的原始值,因此计算出用户位置和新的 trailLocation 点之间的距离是错误的。我不明白为什么这是因为所有其他函数都使用正确的状态值。我将这些值记录下来,我可以使用初始状态清楚地看到它,但是所有其他操作都使用当前状态并且新的 trailLocation 参数显示在屏幕上。
如有任何帮助,我们将不胜感激。我可以提供更多详细信息,这是我的第一个问题,所以请让我松懈 ;)
谢谢
- 删除等待
axios.get(BACKEND_URL + 'api/v1/trails/' + trail.id + '/user/' + credentials.username + '/next-location?include=trail_location_ar_object.ar_object.ar_object_resources', {
headers: {
Authorization: 'Bearer ' + credentials.password,
},
},
)
.then(response => {
setTrailLocation(response.data.data.trail_location);
setIsLoading(false);
setUserWithinRange(false);
})
.catch(error => {
console.log(error);
});
或
2.
let getNextLocation = async () => {
setIsLoading(true);
const credentials = await Keychain.getGenericPassword();
const response = await axios.get(BACKEND_URL + 'api/v1/trails/' + trail.id + '/user/' + credentials.username + '/next-location?include=trail_location_ar_object.ar_object.ar_object_resources', {
headers: {
Authorization: 'Bearer ' + credentials.password,
},
},
)
if(response?.data?.data?.trail_location){
setTrailLocation(response.data.data.trail_location);
}
setIsLoading(false);
setUserWithinRange(false);
};
您的函数中的数据已过时 - 通常称为“陈旧闭包”。当你写 Geolocation.watchPosition((data) => newPositionHandler(data), ...
时,函数是用当时存在的状态创建的。当函数运行时,此数据已过时。
您可以在这个相关问题中阅读有关此问题解决方案的更多信息:
我正在制作一个“寻宝”小径应用程序。用户可以去一个位置,当他们到达那个位置时,一个动作就会发生。为了监控用户位置,我使用来自“react-native-geolocation-service”的 Gelocation.watchposition()。
兴趣点 (trailLocation) 是从我们的 API 中获取的,我用它设置了“trailLocation”状态,它正确更新并且一切看起来都不错。 (initialTrailLocation passed from previous screen)
const [trailLocation, setTrailLocation] = useState(initialTrailLocation);
/**
* Function to get the next trail location
*/
let getNextLocation = async () => {
setIsLoading(true);
const credentials = await Keychain.getGenericPassword();
await axios.get(BACKEND_URL + 'api/v1/trails/' + trail.id + '/user/' + credentials.username + '/next-location?include=trail_location_ar_object.ar_object.ar_object_resources', {
headers: {
Authorization: 'Bearer ' + credentials.password,
},
},
)
.then(response => {
setTrailLocation(response.data.data.trail_location);
setIsLoading(false);
setUserWithinRange(false);
})
.catch(error => {
console.log(error);
});
};
/**
* Function called when the position changes
*/
function newPositionHandler(data) {
console.log("new position handler");
let radius = 1000;
let ky = 40000 / 360;
console.log(trailLocation);
let kx = Math.cos((Math.PI * trailLocation.lat) / 180.0) * ky;
let dx = Math.abs(trailLocation.lon - data.coords.longitude) * kx;
let dy = Math.abs(trailLocation.lat - data.coords.latitude) * ky;
setDistance(Math.sqrt(dx * dx + dy * dy));
console.log(Math.sqrt(dx * dx + dy * dy));
console.log('-------------------');
if(Math.sqrt(dx * dx + dy * dy) <= radius / 1000) {
setUserWithinRange(true);
} else {
setUserWithinRange(false)
}
};
/** Function called to initialise the watch position functionality */
async function watchPosition() {
console.log("watch position");
Geolocation.watchPosition((data) => newPositionHandler(data), (error) => console.log(error),{
enableHighAccuracy: false,
timeout: 10000,
maximumAge: 1000,
distanceFilter: 5,
},
);
};
但是,当 watchposition 的成功函数被触发时,它使用“trailLocation”状态的原始值,因此计算出用户位置和新的 trailLocation 点之间的距离是错误的。我不明白为什么这是因为所有其他函数都使用正确的状态值。我将这些值记录下来,我可以使用初始状态清楚地看到它,但是所有其他操作都使用当前状态并且新的 trailLocation 参数显示在屏幕上。
如有任何帮助,我们将不胜感激。我可以提供更多详细信息,这是我的第一个问题,所以请让我松懈 ;)
谢谢
- 删除等待
axios.get(BACKEND_URL + 'api/v1/trails/' + trail.id + '/user/' + credentials.username + '/next-location?include=trail_location_ar_object.ar_object.ar_object_resources', {
headers: {
Authorization: 'Bearer ' + credentials.password,
},
},
)
.then(response => {
setTrailLocation(response.data.data.trail_location);
setIsLoading(false);
setUserWithinRange(false);
})
.catch(error => {
console.log(error);
});
或 2.
let getNextLocation = async () => {
setIsLoading(true);
const credentials = await Keychain.getGenericPassword();
const response = await axios.get(BACKEND_URL + 'api/v1/trails/' + trail.id + '/user/' + credentials.username + '/next-location?include=trail_location_ar_object.ar_object.ar_object_resources', {
headers: {
Authorization: 'Bearer ' + credentials.password,
},
},
)
if(response?.data?.data?.trail_location){
setTrailLocation(response.data.data.trail_location);
}
setIsLoading(false);
setUserWithinRange(false);
};
您的函数中的数据已过时 - 通常称为“陈旧闭包”。当你写 Geolocation.watchPosition((data) => newPositionHandler(data), ...
时,函数是用当时存在的状态创建的。当函数运行时,此数据已过时。
您可以在这个相关问题中阅读有关此问题解决方案的更多信息: