React组件更新异常:setInterval定时更新状态但时间未刷新
问题分析与解决
你碰到的这个问题很典型,核心原因是你只在组件挂载时创建了一次Date对象,之后定时器里一直复用这个固定的时间值,自然没法实时更新啦!
具体问题出在哪?
在componentDidMount里,你写了const today = new Date();——这行代码只会在组件首次挂载时执行一次,拿到的是组件刚加载那一刻的时间。之后每秒触发的setInterval回调里,你一直用这个已经“过期”的today对象来生成日期和时间字符串,所以state里的curDate和curTime永远是同一个值,页面当然不会重新渲染更新时间了(虽然控制台一直在打印Hello!,但state根本没变化)。
修正后的代码
把new Date()移到定时器的回调函数内部,让每一秒都生成一个新的Date对象,这样就能拿到实时时间了:
import React, { Component } from 'react'; import DateDay from '../Date/Date'; import Time from '../Time/Time'; import './timedate.css' class TimeDate extends Component{ state = { curDate: '', curTime: '', }; componentDidMount() { const optionsDate = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; const optionsTime = { hour: '2-digit', minute: '2-digit' }; // 保存定时器ID,方便后续清除 this.intervalId = setInterval( () => { // 每次定时器触发都创建新的Date对象 const today = new Date(); this.setState({ curDate: today.toLocaleString("en-us", optionsDate), curTime: today.toLocaleString("en-us", optionsTime).slice(0, -3) }); console.log('Hello!') }, 1000) } // 组件卸载时清除定时器,避免内存泄漏 componentWillUnmount() { clearInterval(this.intervalId); } render () { const { curDate, curTime } = this.state; return ( <div className="timedate"> <DateDay dateDay={curDate} /> <Time time={curTime} /> </div> ); } } export default TimeDate;
额外小提示
- 我把两次
setState合并成了一次,这样更高效,避免不必要的重复渲染。 - 新增了
componentWillUnmount生命周期函数来清除定时器——如果组件被卸载但定时器还在运行,会造成内存泄漏,这是React开发里的好习惯哦!
内容的提问来源于stack exchange,提问作者Nick Wood
相关产品推荐
相关产品推荐

