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

React中实现文本切换时重复触发打字机动画的方法

解决React文本切换时重复触发打字机动画的问题

问题背景

我在React组件中实现了每4秒随机切换文本的功能,但当前的打字机动画仅在组件初始加载时触发,无法在每次文本切换时重复执行。相关代码如下:

JSX结构

<div className="fullscreen-text">
   <p>{loadingPhrases[phraseIndex]}</p>
</div>

文本切换逻辑

useEffect(() => {
  const interval = setInterval(() => {
    setPhraseIndex(Math.floor(Math.random() * 9));
  }, 4000);
  return () => clearInterval(interval);
}, []);

当前CSS样式

.fullscreen-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: #fff;
  font-size: 36px;
  font-family: 'Open Sans', sans-serif;
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  animation: typewriter 5s steps(60) forwards;
}

@keyframes typewriter {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

解决方案

下面提供三种可行的实现方式,按需选择:

方法1:利用React的key属性强制重渲染

React会根据元素的key值判断是否需要重新创建组件。当phraseIndex变化时,更新key值即可让组件重新挂载,从而触发CSS动画:

<div className="fullscreen-text" key={phraseIndex}>
   <p>{loadingPhrases[phraseIndex]}</p>
</div>

这种方式最简单,无需修改CSS或额外逻辑,适合快速解决问题。

方法2:手动控制动画类的添加与移除

将动画定义在单独的CSS类中,通过状态控制类的添加/移除,每次文本切换时重置动画:

  1. 修改CSS,拆分基础样式与动画类:
.fullscreen-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: #fff;
  font-size: 36px;
  font-family: 'Open Sans', sans-serif;
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
}

.typewriter-animate {
  animation: typewriter 5s steps(60) forwards;
}

@keyframes typewriter {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}
  1. 在组件中添加状态控制动画:
import { useState, useEffect } from 'react';

// 组件内部状态
const [isAnimating, setIsAnimating] = useState(true);

// 当phraseIndex变化时重置动画
useEffect(() => {
  // 先移除动画类
  setIsAnimating(false);
  // 延迟10ms让浏览器识别样式变化,再重新添加动画类
  const timer = setTimeout(() => setIsAnimating(true), 10);
  return () => clearTimeout(timer);
}, [phraseIndex]);

// JSX部分
<div className={`fullscreen-text ${isAnimating ? 'typewriter-animate' : ''}`}>
   <p>{loadingPhrases[phraseIndex]}</p>
</div>

方法3:使用Web Animations API手动触发

通过原生JS的Web Animations API直接控制动画,灵活性更强,无需依赖CSS类的切换:

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

// 组件内部
const textContainerRef = useRef(null);

// 每次phraseIndex变化时触发动画
useEffect(() => {
  const container = textContainerRef.current;
  if (!container) return;

  // 重置宽度为0
  container.style.width = '0';
  // 执行打字机动画
  container.animate(
    [{ width: '0' }, { width: '100%' }],
    {
      duration: 5000,
      steps: 60,
      fill: 'forwards'
    }
  );
}, [phraseIndex]);

// JSX部分
<div className="fullscreen-text" ref={textContainerRef}>
   <p>{loadingPhrases[phraseIndex]}</p>
</div>

此时可以移除原CSS中的animation属性,保留基础布局样式即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:42:05