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

如何配置Toastify使其仅在指定时间前5分钟显示一次?

解决Toastify仅在指定时间前5分钟显示一次的问题

原代码的核心问题

  • currentTime在useEffect初始化时就固定了,后续定时器循环里一直用这个旧时间做判断,一旦时间匹配,每分钟都会触发一次通知
  • 没有标记toast是否已经显示过,关闭后会被重复触发

优化方案

通过记录toast显示状态+精准定时触发+及时清理定时器可以解决问题,具体修改如下:

import { useState, useEffect } from 'react';
import { toast, ToastContainer } from 'react-toastify';
import { InfoOutlinedIcon } from '@mui/icons-material';
import 'react-toastify/dist/ReactToastify.css';

export default function App() {
  const [time, setTime] = useState(null);
  // 新增状态:标记toast是否已经显示过
  const [hasShownToast, setHasShownToast] = useState(false);

  useEffect(() => {
    const targetTime = new Date(2022, 11, 20, 11, 7); // 注意:月份从0开始,11代表12月
    const reminderTime = new Date(targetTime - 5 * 60000);
    const currentTime = new Date();

    // 页面刷新时,如果已过提醒时间或toast已显示,直接退出逻辑
    if (currentTime > reminderTime || hasShownToast) {
      return;
    }

    // 计算距离提醒时间的毫秒数,用setTimeout实现精准单次触发
    const timeUntilReminder = reminderTime - currentTime;
    const reminderTimeout = setTimeout(() => {
      if (!hasShownToast) {
        notify();
        setHasShownToast(true); // 标记为已显示,避免重复触发
      }
    }, timeUntilReminder);

    // 实时更新当前时间的定时器
    const timeUpdateInterval = setInterval(() => {
      setTime(new Date());
    }, 1000);

    // 清理所有定时器,避免内存泄漏
    return () => {
      clearTimeout(reminderTimeout);
      clearInterval(timeUpdateInterval);
    };
  }, [hasShownToast]); // 依赖hasShownToast,状态变化时重新校验逻辑

  const notify = () =>
    toast(customMsg, {
      icon: <InfoOutlinedIcon />,
      autoClose: false,
      closeOnClick: false
    });

  const customMsg = () => (
    <div>
      Hello Toaster Test
      <div>123</div>
    </div>
  );

  return (
    <div>
      <div>{time ? time.toString() : "Loading"}</div>
      <ToastContainer limit={1} />
    </div>
  );
}

关键修改说明

  1. 用setTimeout替代setInterval:直接计算距离提醒时间的间隔,到点触发一次就结束,彻底避免循环触发的问题
  2. 新增hasShownToast状态:标记toast是否已显示,即使页面刷新,只要状态未重置就不会重复弹出(如果需要持久化,可搭配localStorage)
  3. 前置时间校验:初始化时先判断当前时间是否已过提醒节点,避免页面刷新后在过期时间后仍触发通知
  4. 完整清理定时器:在useEffect的清理函数中同时清理提醒定时器和时间更新定时器,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:10:16