为什么在 React 中使用清理功能(useEffect)不清除 setTimeOut?
Why does the setTimeOut not being cleared by using clean up function in React (useEffect)?
我想在卸载组件时清除所有 setTimeOut。
即使我使用 clearTimeOut 作为清理函数,但错误仍然存在:"Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function"
useEffect(() => {
const timeOut = {timeout1: ()=>setTimeout(() => setProgress((preV) => preV + 15), [
550,
]),timeout2 : ()=> setTimeout(() => setMessage("All most done"), [500])}
timeOut.timeout1();
timeOut.timeout2();
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
};
}, [progress,message]);
有谁知道如何解决这个问题?如有任何帮助,我们将不胜感激!
timeout1 不是存储 setTimeout 的返回值,即 timerId,而是存储执行超时的函数的引用
您可以使用 Immediately invoked functions
以立即执行超时的方式编写代码,以便 timeout1
和 timeout2
具有 timerIds
useEffect(() => {
const timeOut = {
timeout1: (()=>setTimeout(() => setProgress((preV) => preV + 15), 550))(),
timeout2 : (()=> setTimeout(() => setMessage("All most done"), 500))()
}
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
};
}, [progress,message]);
但是你可以简单地 运行 超时而不用将它们写成 IIFE
useEffect(() => {
const timeOut = {
timeout1: setTimeout(() => setProgress((preV) => preV + 15), 550),
timeout2 : ()=> setTimeout(() => setMessage("All most done"), 500)
}
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
};
}, [progress,message]);
如何使用一个局部变量来跟踪组件是否已安装。
useEffect(() => {
let run = true;
const timeOut = {
timeout1: () => setTimeout(() => setProgress((preV) => preV + 15), [550]),
timeout2: () => setTimeout(() => setMessage('All most done'), [500]),
};
if (run) {
timeOut.timeout1();
timeOut.timeout2();
}
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
run = false;
};
}, [progress, message]);
我想在卸载组件时清除所有 setTimeOut。 即使我使用 clearTimeOut 作为清理函数,但错误仍然存在:"Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function"
useEffect(() => {
const timeOut = {timeout1: ()=>setTimeout(() => setProgress((preV) => preV + 15), [
550,
]),timeout2 : ()=> setTimeout(() => setMessage("All most done"), [500])}
timeOut.timeout1();
timeOut.timeout2();
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
};
}, [progress,message]);
有谁知道如何解决这个问题?如有任何帮助,我们将不胜感激!
timeout1 不是存储 setTimeout 的返回值,即 timerId,而是存储执行超时的函数的引用
您可以使用 Immediately invoked functions
以立即执行超时的方式编写代码,以便 timeout1
和 timeout2
具有 timerIds
useEffect(() => {
const timeOut = {
timeout1: (()=>setTimeout(() => setProgress((preV) => preV + 15), 550))(),
timeout2 : (()=> setTimeout(() => setMessage("All most done"), 500))()
}
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
};
}, [progress,message]);
但是你可以简单地 运行 超时而不用将它们写成 IIFE
useEffect(() => {
const timeOut = {
timeout1: setTimeout(() => setProgress((preV) => preV + 15), 550),
timeout2 : ()=> setTimeout(() => setMessage("All most done"), 500)
}
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
};
}, [progress,message]);
如何使用一个局部变量来跟踪组件是否已安装。
useEffect(() => {
let run = true;
const timeOut = {
timeout1: () => setTimeout(() => setProgress((preV) => preV + 15), [550]),
timeout2: () => setTimeout(() => setMessage('All most done'), [500]),
};
if (run) {
timeOut.timeout1();
timeOut.timeout2();
}
return () => {
clearTimeout(timeOut.timeout1);
clearTimeout(timeOut.timeout2);
run = false;
};
}, [progress, message]);