在setInterval中无法更新React状态问题求助
问题分析与修复
核心问题
- useEffect依赖错误:你把
duration放进了useEffect的依赖数组,每次调用setDuration更新状态后,useEffect都会重新执行——销毁旧定时器,再新建一个。这会导致定时器频繁重置,完全没必要。 - 分钟计算逻辑错误:用
(dayjs().minute(diff) as any).$m获取分钟数是错误的,minute()方法是设置当前时间的分钟值,不是处理总分钟数差值,会导致计算结果完全不符合预期。 - 闭包隐患:
calculateTimeDifference每次组件渲染都会重新创建,若不处理可能导致定时器执行异常。
修复后的代码
import { useEffect, useState } from 'react'; import dayjs from 'dayjs'; const YourComponent = () => { const [duration, setDuration] = useState(''); const calculateTimeDifference = () => { const currentDate = dayjs(); const reservationFinishDate = dayjs('2023-03-30T11:00:00.000Z'); // 计算总分钟数差值 const totalMinutes = reservationFinishDate.diff(currentDate, 'minutes', true); // 计算小时数(取整) const hours = Math.floor(totalMinutes / 60); // 计算剩余分钟数(取整) const minutes = Math.floor(totalMinutes % 60); // 更新状态 setDuration(`${hours}h ${minutes}m`); }; useEffect(() => { // 组件启动时立即执行一次 calculateTimeDifference(); // 设置60秒定时器(调试时可改回1000毫秒) const interval = setInterval(calculateTimeDifference, 60000); // 组件卸载时清除定时器 return () => clearInterval(interval); }, []); // 空依赖数组,仅在组件挂载/卸载时执行 return <div>{duration}</div>; }; export default YourComponent;
关键说明
- 移除
duration依赖:空依赖数组保证useEffect只在组件挂载时执行一次,定时器不会被频繁重置。 - 修正分钟计算:用
totalMinutes % 60取余数得到剩余分钟数,再取整,这是时间差计算的正确方式。 - 保留初始执行:组件挂载时先调用一次计算函数,满足“启动时执行一次”的需求,之后每60秒自动执行一次。
内容的提问来源于stack exchange,提问作者Jacki
相关产品推荐
相关产品推荐

