Javascript 为什么我的递归函数不使用更新的状态值?

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

我试图不断检查用户的当前位置是否在地图上标记的100米范围内

我使用一个递归函数来实现这一点,该函数使用哈弗森公式根据当前位置检查所有标记。第一次调用recursive checkMarkers()函数时,数组标记为空

通过log语句,我可以看到递归函数仍在运行,但当标记的状态更改时,它不会反映在checkMarkers()中


看起来您希望每秒记录一次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
中的内容是否应该更新状态?像call
addMarker
?您似乎只是直接从函数体调用了
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);
}, []);