如果您需要连续刷新,那么为什么不使用间隔呢?截至目前,您的递归没有中断条件,因此当组件卸载时它可能仍会运行(我对此不确定,所以不要引用我的话),您可以在间隔期间开始在卸载时停止它:
const intervalId = useRef()
const startCoordinate = {latitude: 51.493280, longitude: 4.294605 }
const calcLocationDist = async (coordinate=startCoordinate)=>{
let currentCoordinate = await Location.getCurrentPositionAsync({
enableHighAccuracy: true
});
SetDistance(getPreciseDistance(coordinate,currentCoordinate)
}
useEffect(()=>{
intervalId.current = setInterval(()=>{
calcLocationDist();
},1000)
// for component unmounts
return ()=>{
clearInterval(intervalId.current)
}
},[])
您可以更进一步,创建一个 useCurrentLocation 挂钩。它可以让您做更多事情而不会弄乱使用它的组件:
const defaultConfig = {
// interval updates in seconds
updateInterval=10,
}
export default function useCurrentLocation({onUpdate, onError,updateInterval}=defaultConfig){
// track errors
const [error, setError] = useState(null);
const [value, setValue] = useState({});
// toggle the interval on and off
const [shouldUpdate, setShouldUpdate] = useState(true);
const intervalId = useRef()
const update = async ()=>{
try{
let loc = await Location.getCurrentPositionAsync({
enableHighAccuracy: true
});
setValue(loc);
onUpdate?.(loc);
} catch(err){
setError(err)
onError?.(setShouldUpdate,error)
}
}
useEffect(()=>{
if(shouldUpdate){
intervalId.current = setInterval(()=>{
update()
},updateInterval*1000)
}
else
clearInterval(intervalId.current)
}
return ()=>{
clearInterval(intervalId.current)
}
},[shouldUpdate])
return {
value,
error,
shouldUpdate:setShouldUpdate
}
}
然后在使用位置的组件中:
const startCoordinate = {latitude: 51.493280, longitude: 4.294605 };
const [permissionStatus, requestPermission] = Location.useForegroundPermissions();
const location = useCurrentLocation({
updateInterval:5,
onUpdate:newLocation=>{
SetDistance(getPreciseDist(startCoordinate,newLocation))
},
onError:(error,shouldUpdate)=>{
console.log(error)
// stop interval
shouldUpdate(false)
}
});
// location.value is current location
console.log(location.value)
// location.error is last error
console.log(location.error)
// location.shouldUpdate is a function that will accept a boolean
// that will turn the interval on or off
useEffect(()=>{
// if permission is granted turn interval on
if(permissionStatus?.granted)
location.shouldUpdate(true)
else{
// turn interval off
location.shouldUpdate(false)
// if permission can be request again attempt to do so
if(permissionStatus.canAskAgain)
requestPermission()
}
},[permissionStatus])