我在 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)
我尝试了其他一些奇怪的想法,但没有任何效果,我无法弄清楚这个。
想法?
整天致力于此 - 在 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)
})
}
您遇到的问题源于创建超时以及尝试清除超时的范围和时间。
由于超时是在
_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
);
}
useRef
,我们创建一个可以保存超时 ID 的持久引用 (timeoutRef
)。该引用在内容更改时不会触发重新渲染,因此非常适合此用例。_getData
内部,获取数据后,我们将超时ID分配给timeoutRef.current
。这使得超时 ID 可在 _getData
外部访问,特别是在 useEffect
清理功能中。useEffect
清理功能中,我们检查timeoutRef.current
是否有值并使用clearTimeout
将其清除。这确保了如果组件卸载,任何活动超时都会被取消,从而防止未安装组件上的状态更新(这将导致 React 错误)。