React Native setTimeout - 如何清除超时

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

我在 useEffect 之外进行了 setTimeout 调用,如何在屏幕卸载时清除超时?

例如,我有一个功能组件,里面有这个......

...

useEffect(() => {
  return () => clearTimeout(myTimeout)
}, [])

_getData = () => {
  fetch()
  .then(data => {
    let myTimeout = setTimeout(() => setSomething(!something), 5000)
  })
}

所以稍后在代码中的某个地方我调用 _getData() - 我不希望在页面首次加载时使用 useEffect 运行它,只有在采取某些操作时才运行。获取数据后,我设置了超时。但 useEffect 不知道这个超时。

我尝试过这样设置超时...

_getData... 
  setTimeoutVar(setTimeout(() => setSomething(!something), 5000))

useEffect...
 return () => clearTimeout(setTimeoutVar)

我尝试了其他一些奇怪的想法,但没有任何效果,我无法弄清楚这个。

想法?

react-native settimeout cleartimeout
2个回答
1
投票

整天致力于此 - 在 stackoverflow 上写一个问题并在两分钟内找出答案。疯了!

这个问题的答案是将一个变量设置为 false,然后在获取数据时更改该变量。然后有一个单独的 useEffect() 函数只处理这个问题。当变量改变时它就会运行。如果变量为 true - 设置超时并且 useEffect 函数返回clearTimeout...

const [refresh, setRefresh] = useState(false)

useEffect(() => {
  let timeoutVariable

  if(refresh){
    timeoutVariable = setTimeout(() => setRefresh(false), 5000)
  }

  return () => clearTimeout(timeoutVariable)

}, [refresh]) 

_getData = () => {
  fetch()
  .then(data => {
    setRefresh(true)
  })
}

0
投票

您遇到的问题源于创建超时以及尝试清除超时的范围和时间。

由于超时是在

_getData
函数中定义的,因此在您尝试清除它的
useEffect
清理函数中无法访问它。

为了确保在组件卸载时可以清除超时,您需要以可在

_getData
函数和
useEffect
清理函数中访问的方式存储超时引用。

实现此目的的一种方法是使用

ref
(通过
useRef
)来存储超时 ID。这种方法确保超时 ID 可以跨渲染持续访问,并且可以在不导致额外渲染的情况下进行修改。

以下是调整代码的方法:

import React, { useState, useEffect, useRef } from 'react';

function YourComponent() {
  // State to manage something
  const [something, setSomething] = useState(false);
  // Ref to store the timeout ID
  const timeoutRef = useRef(null);

  useEffect(() => {
    // Cleanup function to clear the timeout when the component unmounts
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);

  const _getData = () => {
    fetch()
    .then(data => {
      // Save the timeout ID in the ref
      timeoutRef.current = setTimeout(() => setSomething(!something), 5000);
    })
  };

  // Remember to call _getData somewhere in your component, like in response to an event

  return (
    // Your component JSX
  );
}
  1. Ref 用法: 使用
    useRef
    ,我们创建一个可以保存超时 ID 的持久引用 (
    timeoutRef
    )。该引用在内容更改时不会触发重新渲染,因此非常适合此用例。
  2. 设置超时:
    _getData
    内部,获取数据后,我们将超时ID分配给
    timeoutRef.current
    。这使得超时 ID 可在
    _getData
    外部访问,特别是在
    useEffect
    清理功能中。
  3. 清除超时:
    useEffect
    清理功能中,我们检查
    timeoutRef.current
    是否有值并使用
    clearTimeout
    将其清除。这确保了如果组件卸载,任何活动超时都会被取消,从而防止未安装组件上的状态更新(这将导致 React 错误)。
© www.soinside.com 2019 - 2024. All rights reserved.