You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现无需刷新页面自动更新下一个礼拜时间显示?

自动更新下一个礼拜时间的实现方案

问题背景

需要实现当当前时间超过已显示的礼拜时间时,自动切换到下一个_jammah礼拜时间,无需手动刷新页面。此前尝试用useState触发重渲染时出现无限循环,仅能在页面刷新时更新显示内容。

重构思路

  • 禁止在渲染逻辑中直接调用状态更新函数,避免触发无限重渲染
  • 用useEffect结合定时器,计算当前时间到下一个礼拜时间的间隔,时间到后自动更新状态
  • 提前提取并排序所有_jammah时间,简化后续查找逻辑

完整代码示例

import { useState, useEffect } from 'react';
import dayjs from 'dayjs';

const timetable = {
    "fajr_begins": "5:54",
    "fajr_jammah": "6:14",
    "zuhr_begins": "12:51",
    "zuhr_jammah": "13:30",
    "asr_begins": "15:28",
    "asr_jammah": "14:10",
    "maghrib_begins": "18:04",
    "maghrib_jammah": "19:49",
    "isha_begins": "19:27",
    "isha_jammah": "20:00"
};

export default function PrayerTime() {
    const [nextPrayer, setNextPrayer] = useState(null);

    // 提取并排序所有jammah时间
    const getSortedJammahTimes = () => {
        return Object.entries(timetable)
            .filter(([key]) => key.endsWith("_jammah"))
            .map(([name, timeStr]) => ({
                name,
                time: dayjs(timeStr, 'hh:mm'),
                timeStr
            }))
            .sort((a, b) => a.time.diff(b.time));
    };

    // 查找当前下一个礼拜时间
    const findNextPrayer = () => {
        const now = dayjs();
        const sortedTimes = getSortedJammahTimes();
        
        // 优先找当天未到的时间
        let next = sortedTimes.find(prayer => prayer.time.isAfter(now));
        
        // 当天所有时间已过时,自动切换到次日第一个礼拜时间
        if (!next) {
            next = {
                ...sortedTimes[0],
                time: sortedTimes[0].time.add(1, 'day')
            };
        }
        
        return next;
    };

    // 初始化+自动更新下一个礼拜时间
    useEffect(() => {
        const updateNextPrayer = () => {
            const prayer = findNextPrayer();
            setNextPrayer(prayer);
            
            // 计算剩余时间,设置定时器触发下一次更新
            const timeUntilNext = prayer.time.diff(dayjs());
            const timer = setTimeout(updateNextPrayer, timeUntilNext);
            
            return () => clearTimeout(timer);
        };

        const cleanup = updateNextPrayer();
        return cleanup;
    }, []);

    if (!nextPrayer) return <div>加载中...</div>;

    return (
        <div>
            <h3>下一个礼拜:{nextPrayer.name.replace('_jammah', '')}</h3>
            <p>时间:{nextPrayer.timeStr}</p>
            <p>剩余时间:{nextPrayer.time.fromNow()}</p>
        </div>
    );
}

关键说明

  • 预处理排序:提前提取所有_jammah时间并排序,避免每次遍历整个对象,提升查找效率
  • 定时器驱动更新:每次找到下一个礼拜时间后,计算剩余间隔并设置定时器,时间到后自动触发状态更新,彻底避免无限循环
  • 跨天处理:当天所有礼拜时间已过时,自动切换到次日第一个礼拜时间
  • 内存泄漏防护:组件卸载时自动清除定时器,避免内存泄漏

内容的提问来源于stack exchange,提问作者Contradicted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:50:28