当我们使用 setTimeout 时,通常我们不必去考虑清理它。但是,将其引入 React 会产生一些棘手的偶发事件。
这种情况时有发生,因为当我们想在某个时间点之后对数据进行操作,但那时组件可能已经被卸载了,但 setTimeout 仍在试图运行。所以你可能会遇到组件交互被强制恢复、内存泄漏等情形。
那么我们来清晰地使用 setTimeOut() 吧!
总体来说是我们可以追踪代码中创建的超时并用 useEffect 来清理它们。
一个简单的案例可以这样:在CodeSandBox中运行
// App.tsx
import { useState, useEffect } from "react";
export default function App() {
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
const timer = setTimeout(() => {
setIsLoading(false);
}, 3000);
return () => {
clearInterval(timer);
};
}, []);
return (
<>{isLoading ? <span>Loading...</span> : <p>I'm fully loaded now</p>}</>
);
}
当然,我们也可以使用 参照(reference),useRef() 来清除定时器。
import { useState, useEffect, useRef } from "react";
export default function App() {
const [isLoading, setIsLoading] = useState(false);
const timeoutRef = useRef(0);
useEffect(() => {
setIsLoading(true);
timeoutRef.current = window.setTimeout(() => {
setIsLoading(false);
}, 3000);
return () => clearInterval(timeoutRef.current);
}, []);
return (
<>{isLoading ? <span>Loading...</span> : <p>I'm fully loaded now</p>}</>
);
}