无法清除清除超时

问题描述 投票:0回答:1

我正在开发一个使用 React Native 的项目。在该项目中,我有一个屏幕可以检测是否存在人脸。我试图在检测到面部时设置一个计时器,然后清除它,如果面部失去焦点或离开屏幕,则从 0 重新启动。我尝试查看许多使用

setTimeout()
clearTimeout()
的用例示例,但我似乎无法弄清楚为什么这不起作用。当一张脸从屏幕上消失时,它会停止计数,但是当一张脸回到屏幕上时,它会继续从最后一个值开始计数,而不是从 0 开始计数,因此,如果一张脸在 14932 处离开屏幕,那么当该脸回来时在屏幕上,它 (
console.log('timer')
) 会显示
{"current": 14952}
而不是 0。我非常感谢任何有关如何使其正常工作的帮助或建议。谢谢!

const getCountTimeout = (set) => {
    if (set === true ){
    timer.current = setTimeout(() => {
      setTimeoutCount(countRef.current);
      setTimeExtended(true)
    }, 15000)
    }
    else if (set === false) {
      clearTimeout(timer.current);
      setCount(0)
      timer.current = null;
    }
}

相机屏幕

export default function CameraScreen() {

const [hasPermission, setHasPermission] = React.useState(false)
const [isCameraReady, setIsCameraReady] = useState(false);
const [camera, setCamera] = useState(null);
const [state, dispatch] = React.useReducer(detectionReducer, initialState);
const [count, setCount] = useState(0);
const [timeoutCount, setTimeoutCount] = React.useState(0)
const [timeExtended, setTimeExtended] = React.useState(false)
const countRef = React.useRef<number>(count);
const timer = React.useRef(null);
//console.log('count', count)

 React.useEffect(() => {
    (async () => {
      const {status} = await Camera.getCameraPermissionsAsync();
      setHasPermission(status === "granted");
    })();
  }, []);

  if (hasPermission === false) {
    return <Text>No access to camera</Text>;
  }

...

const PREVIEW_SIZE = 325
const PREVIEW_RECT = {
  minX: (SCREEN_WIDTH - PREVIEW_SIZE) / 2,
  minY: 50,
  width: PREVIEW_SIZE,
  height: PREVIEW_SIZE
}

const getCountTimeout = (set) => {
    if (set === true ){
    timer.current = setTimeout(() => {
      setTimeoutCount(countRef.current);
      setTimeExtended(true)
    }, 15000)
    }
    else if (set === false) {
      clearTimeout(timer.current);
      setCount(0)
      timer.current = null;
    }
}

const onCameraReady = () => {
     if (state.faceDetected === "yes") {
       setIsCameraReady(true);
    }
  };

const onFacesDetected = (result: FaceDetectionResult) => {
 const faceRect: Rect = {
      minX: face.bounds.origin.x,
      minY: face.bounds.origin.y,
      width: face.bounds.size.width,
      height: face.bounds.size.height
    }
    const edgeOffset = 50
    const faceRectSmaller: Rect = {
      width: faceRect.width - edgeOffset,
      height: faceRect.height - edgeOffset,
      minY: faceRect.minY + edgeOffset / 2,
      minX: faceRect.minX + edgeOffset / 2
    }
    const previewContainsFace = Contains({
      outside: PREVIEW_RECT,
      inside: faceRectSmaller
    })
    if (!previewContainsFace) {
      getCountTimeout(false)
      dispatch({ type: "FACE_DETECTED", payload: "no" })
      return
    }
    ...

    if (state.faceDetected === "yes") {
      getCountTimeout(true)
      dispatch({ type: "FACE_DETECTED", payload: "yes" })
    }
}

return (
  <View>
  <SafeAreaView>
  <MaskedView
    style={styles.absoluteFill}
    maskElement={<View style={styles.mask} />}
  >
    <Camera
      style={styles.absoluteFill}
      ref={ref => setCamera(ref)}
      type={Camera.Constants.Type.front}
      onFacesDetected={onFacesDetected}
      onCameraReady={onCameraReady}
      faceDetectorSettings={{
        mode: FaceDetector.FaceDetectorMode.fast,
        detectLandmarks: FaceDetector.FaceDetectorLandmarks.none,
        runClassifications: FaceDetector.FaceDetectorClassifications.all,
        minDetectionInterval: 125,
        tracking: false
      }}
    >
    <Svg height="100%" width="100%">
        <Circle
        cx={SCREEN_WIDTH/2}
        cy={PREVIEW_SIZE/2 + PREVIEW_RECT.minY}
        r={PREVIEW_SIZE/2}
        stroke="hsl(0,0%, 80%)"
        strokeWidth={15}
        fill="transparent"
        strokeLinecap="round"
      />
         <Circle
        cx={SCREEN_WIDTH/2}
        cy={PREVIEW_SIZE/2 + PREVIEW_RECT.minY}
        r={PREVIEW_SIZE/2}
        stroke="hsl(100,50%,50%)"
        strokeWidth={15}
        fill="transparent"
        strokeDasharray={Circle_Length}
        strokeDashoffset={Circle_Length * position}
        strokeLinecap="round"
      />
    </Svg>
    </Camera>
  </MaskedView>
</View>
)
};
reactjs react-native settimeout cleartimeout
1个回答
0
投票

您的

countRef
是您存储计数的方式,但您还有一个
count
变量。当您停止计时器时,您正在调用
setCount(0)
,但在计时器中您正在增加
countRef.current
的计数。

我会摆脱

const [count, setCount] ...
并简单地使用
currentRef.current
。在您拨打
setCount(0);
的地方,将其更改为
currentRef.current = 0;

© www.soinside.com 2019 - 2024. All rights reserved.