fix: 修复延长有效期后倒计时不立即更新的问题
This commit is contained in:
1 parent
8f2244028c
commit
8147173290
1 file changed
+29
-14
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState, useEffect, useCallback } from 'react'; // fix: 导入 useCallback
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ClockIcon from './icons/Clock'; // 导入时钟图标
|
||||
import RefreshIcon from './icons/RefreshIcon'; // 导入刷新图标
|
||||
@@ -17,8 +17,9 @@ const formatTimeUnit = (unit: number): string => {
|
||||
export function CountdownTimer({ expiryTimestamp, onExtend }: CountdownTimerProps) {
|
||||
const { t } = useTranslation(); // 用于国际化
|
||||
|
||||
// 计算剩余时间的函数
|
||||
const calculateTimeLeft = () => {
|
||||
// 计算剩余时间的函数 (使用 useCallback 避免不必要的重新创建)
|
||||
const calculateTimeLeft = useCallback(() => {
|
||||
// 直接使用最新的 expiryTimestamp prop
|
||||
const difference = expiryTimestamp - Date.now();
|
||||
let timeLeft = {
|
||||
hours: '00',
|
||||
@@ -28,34 +29,48 @@ export function CountdownTimer({ expiryTimestamp, onExtend }: CountdownTimerProp
|
||||
};
|
||||
|
||||
if (difference > 0) {
|
||||
const totalSeconds = Math.floor(difference / 1000);
|
||||
const seconds = totalSeconds % 60;
|
||||
const totalMinutes = Math.floor(totalSeconds / 60);
|
||||
const minutes = totalMinutes % 60;
|
||||
const hours = Math.floor(totalMinutes / 60); // 不再限制 % 24,可以显示超过一天的时间
|
||||
|
||||
timeLeft = {
|
||||
hours: formatTimeUnit(Math.floor((difference / (1000 * 60 * 60)) % 24)),
|
||||
minutes: formatTimeUnit(Math.floor((difference / 1000 / 60) % 60)),
|
||||
seconds: formatTimeUnit(Math.floor((difference / 1000) % 60)),
|
||||
hours: formatTimeUnit(hours),
|
||||
minutes: formatTimeUnit(minutes),
|
||||
seconds: formatTimeUnit(seconds),
|
||||
expired: false,
|
||||
};
|
||||
}
|
||||
|
||||
return timeLeft;
|
||||
};
|
||||
}, [expiryTimestamp]); // expiryTimestamp 作为依赖项
|
||||
|
||||
// 使用 useState 来存储剩余时间
|
||||
const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());
|
||||
|
||||
// 使用 useEffect 来设置定时器,每秒更新剩余时间
|
||||
useEffect(() => {
|
||||
// 如果已经过期,则不设置定时器
|
||||
if (timeLeft.expired) {
|
||||
return;
|
||||
}
|
||||
// 立即计算一次以避免初始延迟
|
||||
setTimeLeft(calculateTimeLeft());
|
||||
|
||||
// 设置定时器
|
||||
const timer = setInterval(() => {
|
||||
setTimeLeft(calculateTimeLeft());
|
||||
}, 1000);
|
||||
|
||||
// 组件卸载时清除定时器
|
||||
// 组件卸载或 expiryTimestamp 变化时清除定时器
|
||||
// fix: 将 expiryTimestamp 添加到依赖项,确保每次时间戳更新时都重置定时器
|
||||
return () => clearInterval(timer);
|
||||
}, [expiryTimestamp, timeLeft.expired]); // 依赖项包含过期时间戳和是否过期状态
|
||||
}, [expiryTimestamp, calculateTimeLeft]); // 依赖项包含 expiryTimestamp 和 calculateTimeLeft
|
||||
|
||||
// 当计算出的时间显示已过期时,停止计时器(通过清除上一个 effect 实现)
|
||||
useEffect(() => {
|
||||
if (timeLeft.expired) {
|
||||
// 定时器已在上面的 effect 的 cleanup 函数中清除
|
||||
// 这里可以额外处理过期逻辑,如果需要的话
|
||||
}
|
||||
}, [timeLeft.expired]);
|
||||
|
||||
return (
|
||||
// feat: 将容器改为 flex-row 并添加按钮
|
||||
@@ -70,7 +85,7 @@ export function CountdownTimer({ expiryTimestamp, onExtend }: CountdownTimerProp
|
||||
</span> // 显示剩余时间 时:分:秒
|
||||
)}
|
||||
</div>
|
||||
{/* feat: 添加延长有效期按钮 */}
|
||||
{/* feat: 添加延长有效期按钮, 仅在未过期时显示 */}
|
||||
{!timeLeft.expired && (
|
||||
<button
|
||||
onClick={onExtend}
|
||||
|
||||
Reference in new issue
Block a user