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

React中useState引发内存溢出与重复渲染问题求助

React时钟组件渲染次数剧增、内存占用过高的解决方案

问题根源

你的代码核心问题在于useEffect的依赖数组包含了time:每次setTime更新state后,useEffect都会重新执行,而每次执行又会创建一个新的setInterval,且旧的定时器从未被清理。这就导致每秒都会新增一批定时器,每个定时器都触发setTime,进而引发更多渲染,最终形成几何级增长的渲染次数和持续飙升的内存占用。

修正后的代码

import React, { useState, useEffect } from "react";
import classes from "./Clock.module.css";

const ClockCurrent = (props) => {
    const [time, setTime] = useState(new Date());

    useEffect(() => {
        // 组件挂载时仅创建一次定时器
        const timerId = setInterval(() => {
            setTime(new Date());
        }, 1000);

        // 组件卸载时清除定时器,避免内存泄漏
        return () => clearInterval(timerId);
    }, []); // 空依赖数组,确保useEffect只执行一次

    // 直接生成格式化时间,轻量操作无需useMemo
    const currentTime = time.toLocaleTimeString("ru", {
        timeZone: "Europe/Moscow",
    });

    return (
        <div className={classes.Clock}>
            <h2>{currentTime}</h2>
        </div>
    );
};

export default ClockCurrent;

关键改动说明

  1. 空依赖数组:将useEffect的依赖改为[],确保组件首次挂载时仅执行一次,只会创建一个定时器,从根源避免了重复创建定时器的问题。
  2. 定时器清理:在useEffect中返回清理函数,组件卸载时自动清除定时器,防止无用定时器占用内存。
  3. 简化逻辑:移除了多余的useMemo——toLocaleTimeString是轻量的字符串格式化操作,缓存它带来的收益远小于代码复杂度,完全可以直接调用。
  4. 移除无效依赖:定时器回调中直接创建新的Date对象,不需要依赖外部的time变量,避免了不必要的state依赖触发重复执行。

补充说明

你之前尝试的useMemo无效,是因为问题的核心不在渲染阶段的计算开销,而在于定时器的重复创建导致的state更新风暴。只要解决了定时器重复创建的问题,渲染次数和内存占用就会恢复正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:55:57