import React, { useState, useEffect } from "react";
function Countdown() {
const [countdown, setCountdown] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
const now = new Date().getTime();
const endTime = new Date("2023-04-01").getTime();
const distance = endTime - now;
// 倒计时不会变成负数,即如果当前时间超过了结束时间,倒计时将显示为0。
setCountdown(Math.max(distance, 0));
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
const days = Math.floor(countdown / (1000 * 60 * 60 * 24));
const hours = ("0" + Math.floor((countdown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))).slice(
-2,
);
const minutes = ("0" + Math.floor((countdown % (1000 * 60 * 60)) / (1000 * 60))).slice(-2);
const seconds = ("0" + Math.floor((countdown % (1000 * 60)) / 1000)).slice(-2);
return (
<div>
<h1>倒计时</h1>
<p>{`${days}天 ${hours}小时 ${minutes}分钟 ${seconds}秒`}</p>
</div>
);
}
export default Countdown;
疑问点:
下述代码是什么时候执行?
return () => {
clearInterval(timer);
};
这代码是每次都要执行的呢?
这段代码不是每次都会执行的,它只在以下情况下才会执行:
- 当组件卸载时。
- 当 useEffect 中的依赖项发生变化时。
在这个示例中,我们使用空数组 [] 作为 useEffect 的依赖项,这意味着 useEffect 中的函数只会在组件挂载时执行一次,因此清理函数也只会在组件卸载时执行一次。
当组件卸载时,React 将自动执行清理函数来清除计时器。这是因为计时器是在 useEffect 中创建的,而 React 会确保在组件卸载时清除由 useEffect 创建的任何资源。因此,我们不必担心清理函数会在其他情况下执行。
总之,return () => { clearInterval(timer); };
这段代码只在组件卸载时执行一次,以清除由 setInterval 创建的计时器。
==补充说明:==
这段代码是使用 useEffect 中的函数作为清理函数(Cleanup Function)。当组件卸载时或 useEffect 中的依赖项发生变化时,React 会先执行清理函数,然后再执行 useEffect 中的函数。在这个例子中,我们使用 setInterval 来更新倒计时,并将返回的计时器 ID 存储在变量 timer 中。为了避免内存泄漏和不必要的计时器运行,我们需要在组件卸载或 useEffect 依赖项发生变化时清除计时器。
因此,这段代码的作用是在组件卸载时清除计时器 timer。我们使用 clearInterval 函数来停止计时器的运行。通过在清理函数中返回这个函数,我们确保了计时器在组件卸载时被清除,从而避免了内存泄漏和不必要的计时器运行。