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
相关产品推荐
相关产品推荐

