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

React Typewriter组件第二个字符丢失问题求助

React Typewriter组件第二个字符丢失问题求助

嗨,我来帮你看看这个打字机组件的问题~

首先,我注意到你的代码里有几个小细节可能就是导致第二个字符丢失的原因,咱们一步步梳理:

  1. useEffect依赖项缺失:你在useEffect里用到了textToWrite和typeSpeed这两个props,但依赖数组是空的[],这会导致React无法在这些props变化时重新执行打字逻辑,还可能引发闭包问题,让index的递增出现异常。
  2. setInterval的终止条件不够严谨:当前的判断index >= textToWrite.length -1容易在字符处理的时机上出现偏差,再加上setInterval本身的闭包特性,可能会让某个字符的赋值被跳过。
  3. 缺少组件卸载时的清理逻辑:如果组件在打字过程中被卸载,残留的interval会导致内存泄漏,甚至尝试更新已卸载组件的状态。

针对这些问题,我给你两种修复方案,选你觉得顺手的就行:

方案一:修复原有的setInterval逻辑

"use client"
import { useEffect, useState } from "react"

type TypewriterProps = {
  textToWrite: string,
  typeSpeed: number
}

function Typewriter({ textToWrite, typeSpeed }: TypewriterProps) {
  const [finalText, setFinalText] = useState("")

  useEffect(() => {
    setFinalText("") // 重新触发打字时先清空文本
    let index = 0
    const interval = setInterval(() => {
      // 改用prev + char的写法,避免字符串赋值的潜在问题
      setFinalText(prev => prev + textToWrite[index])
      index++
      // 当index等于文本长度时,说明所有字符都处理完毕,终止循环
      if (index >= textToWrite.length) {
        clearInterval(interval)
      }
    }, typeSpeed)

    // 组件卸载时清理interval,防止内存泄漏
    return () => clearInterval(interval)
  }, [textToWrite, typeSpeed]) // 添加依赖项,确保props变化时重新执行打字逻辑

  return (
    <p className="mt-5 font-mono font-bold">{finalText}</p>
  )
}

export default Typewriter

方案二:换用setTimeout循环(更推荐,避开闭包陷阱)

这种写法用forEach遍历每个字符,给每个字符设置独立的延迟,逻辑更直观,完全不会有setInterval的闭包问题:

"use client"
import { useEffect, useState } from "react"

type TypewriterProps = {
  textToWrite: string,
  typeSpeed: number
}

function Typewriter({ textToWrite, typeSpeed }: TypewriterProps) {
  const [finalText, setFinalText] = useState("")

  useEffect(() => {
    setFinalText("")
    // 遍历每个字符,按顺序设置延迟执行的赋值操作
    Array.from(textToWrite).forEach((char, i) => {
      setTimeout(() => {
        setFinalText(prev => prev + char)
      }, i * typeSpeed)
    })
  }, [textToWrite, typeSpeed])

  return (
    <p className="mt-5 font-mono font-bold">{finalText}</p>
  )
}

export default Typewriter

你可以试试这两种方案,应该就能解决第二个字符丢失的问题啦~ 作为新手遇到这种问题太正常了,其实核心就是setInterval的闭包和依赖项的小疏漏,换成setTimeout的写法会更省心哦!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:09:50