React中如何在文本变化时更新div?定时器场景技术求助
解决「沃尔多在哪里」Web应用定时器UI不更新问题
你的问题核心是useRef的.current属性变化不会触发React组件重渲染,所以即使你在定时器里更新了hour、second的current值,页面上的div也不会自动刷新。要实现UI随时间变化更新,必须用useState来管理时间状态——useState的更新会触发组件重渲染,从而同步更新UI。
错误点分析
- 原代码未声明
minute的useRef变量,运行时会直接报错 - 使用useRef管理需要驱动UI变化的时间值,无法触发重渲染
- 判断
minute === 60应为minute.current === 60,存在逻辑错误
修改后的完整代码
import { useState, useRef, useEffect } from 'react'; function WaldoTimer() { // 用useState管理时间状态,确保更新时触发重渲染 const [time, setTime] = useState({ hour: '00', minute: '00', second: '00' }); // 无需触发重渲染的变量用useRef保存 const stopTime = useRef(false); const timerId = useRef(null); // 统一格式化时间:小于10补0 const formatTime = (num) => { return num < 10 ? `0${num}` : `${num}`; }; const timerCycle = () => { if (!stopTime.current) { // 基于前一次状态更新,避免状态依赖问题 setTime(prevTime => { let sec = parseInt(prevTime.second) + 1; let min = parseInt(prevTime.minute); let hr = parseInt(prevTime.hour); // 时间进位逻辑 if (sec === 60) { sec = 0; min += 1; } if (min === 60) { min = 0; hr += 1; } // 返回格式化后的新状态 return { hour: formatTime(hr), minute: formatTime(min), second: formatTime(sec) }; }); timerId.current = setTimeout(timerCycle, 1000); } }; // 组件挂载启动定时器,卸载时清理避免内存泄漏 useEffect(() => { timerId.current = setTimeout(timerCycle, 1000); return () => clearTimeout(timerId.current); }, []); // 停止计时的示例方法(按需调用) const stopTimer = () => { stopTime.current = true; clearTimeout(timerId.current); }; return ( <div> <div id="stopwatch">{time.hour}:{time.minute}:{time.second}</div> {/* 可选:添加停止按钮测试 */} <button onClick={stopTimer}>停止计时</button> </div> ); }
关键修改说明
- 用
useState替代useRef管理时间状态,每次setTime都会触发组件重渲染,同步更新UI - 提取
formatTime函数简化重复的补0逻辑 - 用
useRef保存定时器ID和stopTime,这类不需要驱动UI变化的变量用useRef更高效 - 通过
useEffect处理定时器的启动与清理,避免组件卸载后定时器继续运行导致内存泄漏 - 修复原代码中未声明
minute、条件判断错误等问题
内容的提问来源于stack exchange,提问作者Minchan Jung
相关产品推荐
相关产品推荐

