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

React useEffect未触发退出条件:打字机效果组件重复挂载问题

打字机效果的问题分析与修复

你的代码存在几个核心问题,导致组件不断重复更新甚至异常:

  1. 重复创建定时器:每次word状态更新都会触发useEffect,而每次触发都会新建一个setInterval,旧的定时器没有被清理,最终多个定时器同时运行,导致组件频繁更新。
  2. 闭包捕获旧值:定时器回调里的word是创建定时器时的闭包值,不是最新的状态,会导致setWord更新错误。
  3. 无清理逻辑:既没有在组件卸载时清除定时器,也没有在打字完成后终止定时器。

下面是修复后的代码:

import { useState, useEffect, useRef } from 'react';

export default function Typewriter() {
  const name: string = 'Mouhib Ouni';
  const [word, setWord] = useState<string>('');
  // 用useRef保存定时器ID,方便后续清理
  const timerRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    // 只在组件挂载时初始化一次定时器
    timerRef.current = setInterval(() => {
      // 使用函数式更新获取最新的word状态
      setWord(prevWord => {
        if (prevWord.length >= name.length) {
          // 打字完成后清除定时器
          clearInterval(timerRef.current!);
          return prevWord;
        }
        return prevWord + name[prevWord.length];
      });
    }, 1000);

    // 组件卸载时清理定时器
    return () => {
      if (timerRef.current) {
        clearInterval(timerRef.current);
      }
    };
  }, []); // 依赖项为空数组,仅执行一次

  return <div>{word}</div>;
}

关键改动说明:

  • useRef存储定时器ID:确保能在回调和清理函数中访问到同一个定时器实例,避免内存泄漏。
  • 函数式更新setWord:通过prevWord获取最新的状态值,避免闭包带来的旧值问题。
  • 单次初始化定时器:useEffect依赖项为空数组,只在组件挂载时创建一次定时器,不会重复触发。
  • 自动清理逻辑:打字完成后主动清除定时器,同时在组件卸载时也清理定时器,彻底避免无效更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:15:33