如何在react-hot-toast中实现支持悬停暂停的倒计时功能
实现react-hot-toast悬停暂停倒计时方案
你可以直接通过自定义Toast组件+原生计时器逻辑实现需求,无需额外依赖第三方倒计时库,核心逻辑用useRef存储计时相关变量避免React重渲染导致的计时错乱问题,具体实现如下:
核心实现逻辑
用useRef存储倒计时剩余时长、计时器ID、暂停状态三个变量,鼠标进入时清除计时器并记录当前剩余时长,鼠标移出时从剩余时长断点重启倒计时,倒计时结束后手动调用toast.dismiss关闭弹窗即可。
完整可运行代码示例
import { useState, useEffect, useRef } from 'react'; import toast, { Toaster } from 'react-hot-toast'; // 自定义带倒计时的Toast组件 const CountdownToast = ({ id, totalDuration = 5000 }) => { // 计时相关变量用useRef存储,避免重渲染导致的闭包问题 const remainingTimeRef = useRef(totalDuration); const timerRef = useRef(null); const isPausedRef = useRef(false); const [showSecond, setShowSecond] = useState(totalDuration / 1000); // 启动/恢复倒计时方法 const startCountdown = (duration) => { if (timerRef.current) clearInterval(timerRef.current); const startTime = Date.now(); timerRef.current = setInterval(() => { if (isPausedRef.current) return; const elapsedTime = Date.now() - startTime; const leftTime = duration - elapsedTime; // 倒计时结束关闭弹窗 if (leftTime <= 0) { clearInterval(timerRef.current); toast.dismiss(id); return; } remainingTimeRef.current = leftTime; setShowSecond(Math.ceil(leftTime / 1000)); }, 100); }; // 组件挂载启动倒计时 useEffect(() => { startCountdown(totalDuration); return () => clearInterval(timerRef.current); }, []); // 鼠标进入暂停倒计时 const handlePause = () => { isPausedRef.current = true; if (timerRef.current) clearInterval(timerRef.current); }; // 鼠标移出恢复倒计时 const handleResume = () => { isPausedRef.current = false; startCountdown(remainingTimeRef.current); }; return ( <div onMouseEnter={handlePause} onMouseLeave={handleResume} style={{ padding: '12px 16px', background: '#fff', borderRadius: '6px', boxShadow: '0 2px 10px rgba(0,0,0,0.12)' }} > 操作成功,{showSecond}秒后自动关闭 </div> ); }; // 业务组件调用示例 function App() { const triggerToast = () => { toast.custom((t) => <CountdownToast id={t.id} totalDuration={5000} />); }; return ( <div style={{ padding: '20px' }}> <button onClick={triggerToast}>弹出倒计时提示</button> <Toaster /> </div> ); } export default App;
注意事项
- 核心计时变量不要用useState存储,频繁触发重渲染不仅会增加性能损耗,还容易出现闭包导致的计时不准问题
- 所有逻辑都封装在自定义Toast组件内部,不需要修改react-hot-toast全局配置,不会影响项目内其他普通Toast的正常使用
- 如果需要实现进度条样式的倒计时效果,直接通过
remainingTimeRef.current / totalDuration计算进度比例即可快速实现
内容的提问来源于stack exchange,提问作者Freelanx
相关产品推荐
相关产品推荐

