// 请实现一个具有倒计时功能的自定义 Hook,要求可以每秒自动更新并返回当前剩余时间,其返回值满足以下定义: // 返回值定义 interface Countdown { expired: boolean; // 是否已到期 days: number; // 剩余天数(整数),最小为0 hours: number; // 剩余小时数(整数),最大为 23,最小为0 minutes: number; // 剩余分钟数(整数),最大为 59,最小为0 seconds: number; // 剩余秒数(整数),最大为 59,最小为0 } // Notice: // 1. 若剩余时间为0,则停止计时 // 2. 应用程序在压后台时为优化性能,页面容器的tick会变慢(setInterval 1s,可能实际2s以上才会触发一次),基于该情况,请考虑如何准确计时 function useCountdown(expireTime: number): Countdown { }
时间: 2023-04-10 09:02:47 浏览: 152
非常感谢您的问题,我可以回答这个编程类的问题。
以下是一个具有倒计时功能的自定义 Hook 的完整代码,它可以每秒自动更新并返回当前剩余时间:
```typescript
interface Countdown {
expired: boolean; // 是否已到期
days: number; // 剩余天数(整数),最小为0
hours: number; // 剩余小时数(整数),最大为 23,最小为0
minutes: number; // 剩余分钟数(整数),最大为 59,最小为0
seconds: number; // 剩余秒数(整数),最大为 59,最小为0
}
function useCountdown(expireTime: number): Countdown {
const [countdown, setCountdown] = useState<Countdown>({
expired: false,
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
});
useEffect(() => {
let intervalId: NodeJS.Timeout;
const updateCountdown = () => {
const now = Date.now();
const diff = expireTime - now;
if (diff <= 0) {
setCountdown({
expired: true,
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
});
clearInterval(intervalId);
return;
}
const days = Math.floor(diff / (24 * 60 * 60 * 1000));
const hours = Math.floor((diff % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));
const minutes = Math.floor((diff % (60 * 60 * 1000)) / (60 * 1000));
const seconds = Math.floor((diff % (60 * 1000)) / 1000);
setCountdown({
expired: false,
days,
hours,
minutes,
seconds,
});
};
updateCountdown();
intervalId = setInterval(updateCountdown, 1000);
return () => clearInterval(intervalId);
}, [expireTime]);
return countdown;
}
```
这个 Hook 使用了 React 的 useState 和 useEffect,它会在组件挂载时开始计时,并在每秒钟更新剩余时间。如果剩余时间为0,则停止计时。为了准确计时,我们使用了 Date.now() 获取当前时间,并计算出与过期时间的时间差。最后,我们将剩余时间的天数、小时数、分钟数和秒数存储在一个对象中,并返回该对象作为 Hook 的返回值。
希望这个代码可以帮助您实现具有倒计时功能的自定义 Hook。如果您有任何问题,请随时问我。
阅读全文