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

React自定义useTypewriter钩子打字机效果丢失字符问题

React自定义useTypewriter钩子字符丢失问题修复

问题原因

原代码里追踪字符索引的变量i是useEffect内部的局部变量,受React闭包特性影响,当组件因状态更新重新渲染时,旧定时器回调中的i会保留最初捕获的值。如果此时新的useEffect执行并创建新定时器,两个定时器会同时操作displayText状态,导致字符拼接顺序混乱,出现字符丢失或错误的情况。

修复方案

用useRef保存索引值和定时器ID,ref的.current属性在组件生命周期内保持可变,不会被闭包捕获,能确保每次定时器回调都获取到最新的索引值:

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

export const useTypewriter = (text: string, speed: number) => {
  const [displayText, setDisplayText] = useState("");
  const indexRef = useRef(0);
  const intervalRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    // 重置索引和显示文本
    indexRef.current = 0;
    setDisplayText("");
    
    // 清除可能存在的旧定时器
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }

    intervalRef.current = setInterval(() => {
      if (indexRef.current < text.length) {
        setDisplayText(prev => prev + text.charAt(indexRef.current));
        indexRef.current++;
      } else {
        clearInterval(intervalRef.current!);
        intervalRef.current = null;
      }
    }, speed);

    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, [text, speed]);

  return displayText;
};

额外优化说明

  • 用useRef统一管理定时器ID,确保组件卸载或依赖项变化时能彻底清除定时器,避免内存泄漏
  • 每次useEffect执行前手动重置索引和显示文本,保证新的打字动画从文本开头开始执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:43:13