Javascript 为什么我的递归函数不使用更新的状态值?
我试图不断检查用户的当前位置是否在地图上标记的100米范围内 我使用一个递归函数来实现这一点,该函数使用哈弗森公式根据当前位置检查所有标记。第一次调用recursive checkMarkers()函数时,数组标记为空 通过log语句,我可以看到递归函数仍在运行,但当标记的状态更改时,它不会反映在checkMarkers()中Javascript 为什么我的递归函数不使用更新的状态值?,javascript,reactjs,react-native,recursion,react-hooks,Javascript,Reactjs,React Native,Recursion,React Hooks,我试图不断检查用户的当前位置是否在地图上标记的100米范围内 我使用一个递归函数来实现这一点,该函数使用哈弗森公式根据当前位置检查所有标记。第一次调用recursive checkMarkers()函数时,数组标记为空 通过log语句,我可以看到递归函数仍在运行,但当标记的状态更改时,它不会反映在checkMarkers()中 看起来您希望每秒记录一次state/haversine值。使用挂载useffecthook启动一个间隔来调用checkMarkers回调,并记住返回一个清理函数。使用re
看起来您希望每秒记录一次state/haversine值。使用挂载
useffect
hook启动一个间隔来调用checkMarkers
回调,并记住返回一个清理函数。使用ref和附加的useffect
hook保存对当前状态的引用,以便在间隔回调中使用
const markersRef = React.useRef();
React.useEffect(() => {
markersRef.current = markers;
}, [markers]);
React.useEffect(() => {
const checkMarkers = () => {
const markers = markersRef.current;
console.log(markers);
Geolocation.getCurrentPosition(
position => {
markers.forEach(({ latitude, longitude }) => {
console.log(
Haversine(
{ latitude, longitude },
{
latitude: position.coords.latitude,
longitude: position.coords.longitude,
},
{threshold: 100, unit: 'meter'},
),
);
});
},
error => {
console.log(error.code, error.message);
},
{enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
);
};
const intervalId = setInterval(checkMarkers, 1000);
return () => clearInterval(intervalId);
}, []);
checkMarkers
中的内容是否应该更新状态?像calladdMarker
?您似乎只是直接从函数体调用了checkMarkers
,这可能是无意的副作用。调用checkMarkers
时,整个递归调用堆栈将使用调用堆栈存在于渲染周期中的状态。将来,是的。但对于本例,它的唯一目的是打印从Haversine()返回的布尔值,然后使用组件生命周期。您希望何时注销标记
状态/haversine值?哦,我明白了,你只是想每秒注销一次值吗?没错,我只是想根据当前位置是否在标记的100米范围内来判断是真是假
<MapView ...>
{markers.map((marker, i) => {
return (
<MapView.Marker
key={i}
coordinate={marker}
onPress={() => removeMarker(i)}
/>
);
})}
</MapView>
[Info] 05-26 13:38:30.648 27807 31324 I ReactNativeJS: []
[Info] 05-26 13:38:31.664 27807 31324 I ReactNativeJS: []
[Info] 05-26 13:38:32.015 27807 31324 I ReactNativeJS: [ { longitude: 150.8891862630844, latitude: -34.42137027273215 } ]
[Info] 05-26 13:38:32.676 27807 31324 I ReactNativeJS: []
[Info] 05-26 13:38:33.687 27807 31324 I ReactNativeJS: []
[Info] 05-26 13:38:34.694 27807 31324 I ReactNativeJS: []
[Info] 05-26 13:38:34.984 27807 31324 I ReactNativeJS: [ { longitude: [Getter/Setter], latitude: [Getter/Setter] },
05-26 13:38:34.984 27807 31324 I ReactNativeJS: { longitude: 150.89105676859617, latitude: -34.404266529657555 } ]
[Info] 05-26 13:38:35.713 27807 31324 I ReactNativeJS: []
[Info] 05-26 13:38:36.735 27807 31324 I ReactNativeJS: []
const markersRef = React.useRef();
React.useEffect(() => {
markersRef.current = markers;
}, [markers]);
React.useEffect(() => {
const checkMarkers = () => {
const markers = markersRef.current;
console.log(markers);
Geolocation.getCurrentPosition(
position => {
markers.forEach(({ latitude, longitude }) => {
console.log(
Haversine(
{ latitude, longitude },
{
latitude: position.coords.latitude,
longitude: position.coords.longitude,
},
{threshold: 100, unit: 'meter'},
),
);
});
},
error => {
console.log(error.code, error.message);
},
{enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
);
};
const intervalId = setInterval(checkMarkers, 1000);
return () => clearInterval(intervalId);
}, []);