即使离开页面 React js,功能仍在执行

Function is executing even after leaving the page React js

当我从家导航时,即“/”到“/realtime”useEffect hook 从网络摄像头启动视频,然后我为视频 onPlay 事件添加了一个函数 handleVideoPlay,如下所示。

<video
  className="video"
  ref={videoRef}
  autoPlay
  muted
  onPlay={handleVideoPlay}
/>

对于每 100 毫秒的间隔,setInterval 中的代码(在 handleVideoPlay 函数中)将 运行,它使用 faceapi 检测面部情绪并绘制 canvas。

这是我的 handleVideoPlay 函数

const [ isOnPage, setIsOnPage] = useState(true);

  const handleVideoPlay = () => {

    setInterval(async () => {
    if(isOnPage){
      canvasRef.current.innerHTML = faceapi.createCanvasFromMedia(videoRef.current);
      const displaySize = {
        width: videoWidth,
        height: videoHeight,
      };
      faceapi.matchDimensions(canvasRef.current, displaySize);

      const detections = await faceapi.detectAllFaces(videoRef.current, new 
      faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();

      const resizeDetections = faceapi.resizeResults(detections, displaySize);

      canvasRef.current.getContext("2d").clearRect(0, 0, videoWidth, videoHeight);

      faceapi.draw.drawDetections(canvasRef.current, resizeDetections);

      faceapi.draw.drawFaceLandmarks(canvasRef.current, resizeDetections);

      faceapi.draw.drawFaceExpressions(canvasRef.current, resizeDetections);
     }else{
      return;
     }
    }, 100);
  };

问题是当我返回时,handleVideoFunction 仍然是 运行ning,因此对于 canvasRef,它得到的是空值,并且抛出如下所示的错误

Unhandled Rejection (TypeError): Cannot read property 'getContext' of null

我想在离开页面时停止 setInterval 块。我尝试将状态 isOnPage 设置为 true 并且 我在 useEffect 清理中将它设置为 false,这样如果 isOnPage 为真,setInterval 运行s 中的代码否则它 returns。但这没有用。 useEffect 清理函数中的其他代码是 运行ning 但状态没有改变。 请帮我解决这个问题,如果您没有正确提出问题,我深表歉意,如果您需要有关此问题的更多信息来解决,我会给您。 谢谢

卸载组件时,您需要从 运行 中清除 setInterval

您可以使用 useEffect 钩子来做到这一点:

useEffect(() => {
  const interval = setInterval(() => {
    console.log('I will log every second until I am cleared');
  }, 1000);
  return () => clearInterval(interval);
}, []);

将一个空数组传递给 useEffect 可确保该效果在挂载时仅触发 一次

效果return在组件卸载时调用

如果您在此处清除间隔,一旦组件被卸载,您将不再有间隔运行。不仅如此,你还要确保你不会泄漏内存(即通过无限增加后台 运行 的 setIntervals 的数量)。