如何为React组件段落中切换的文本添加动画效果?
实现React文本切换的过渡动画方案
当然可以,不管是纯CSS/SCSS还是React动画库,都能实现两段文本切换时的过渡效果,下面是几种实用方案:
方案一:纯CSS/SCSS实现淡入淡出+位移动画
这种方案无需依赖第三方库,通过调整组件结构让两个文本元素重叠,用类控制显示状态触发过渡动画:
修改后的React组件
const StatusBar = ({ currentPlayer }) => { const isBlackTurn = currentPlayer?.color === Colors.BLACK; return ( <div className="status-bar-container"> <div className="status-text-wrapper"> <p className={`status-text ${isBlackTurn ? 'active' : ''}`}> ⚫️ Black player's turn </p> <p className={`status-text ${!isBlackTurn ? 'active' : ''}`}> ⚪️ White player's turn </p> </div> </div> ) }
对应的SCSS样式
.status-bar-container { position: relative; height: 2rem; /* 固定高度避免容器跳动 */ overflow: hidden; } .status-text-wrapper { position: absolute; top: 0; left: 0; width: 100%; } .status-text { position: absolute; top: 0; left: 0; margin: 0; opacity: 0; transform: translateY(20px); transition: all 0.3s ease-in-out; &.active { opacity: 1; transform: translateY(0); } }
方案二:使用React Transition Group库
这是React生态中常用的动画库,能更灵活地控制元素的进入/退出动画:
第一步:安装依赖
npm install react-transition-group # 或 yarn add react-transition-group
组件代码实现
import { CSSTransition, TransitionGroup } from 'react-transition-group'; const StatusBar = ({ currentPlayer }) => { const statusText = currentPlayer?.color === Colors.BLACK ? "⚫️ Black player's turn" : "⚪️ White player's turn"; return ( <div className="status-bar-container"> <TransitionGroup> <CSSTransition key={statusText} timeout={300} classNames="status-transition" > <p>{statusText}</p> </CSSTransition> </TransitionGroup> </div> ) }
配套SCSS样式
.status-bar-container { position: relative; height: 2rem; overflow: hidden; } .status-transition-enter { opacity: 0; transform: translateY(20px); } .status-transition-enter-active { opacity: 1; transform: translateY(0); transition: all 0.3s ease-in-out; } .status-transition-exit { opacity: 1; transform: translateY(0); } .status-transition-exit-active { opacity: 0; transform: translateY(-20px); transition: all 0.3s ease-in-out; }
方案三:自定义React Hook实现缩放动画
如果不想引入第三方库,也可以用useState和useEffect手动控制动画状态:
组件代码
import { useState, useEffect } from 'react'; const StatusBar = ({ currentPlayer }) => { const [isAnimating, setIsAnimating] = useState(false); const [prevText, setPrevText] = useState("⚪️ White player's turn"); const currentText = currentPlayer?.color === Colors.BLACK ? "⚫️ Black player's turn" : "⚪️ White player's turn"; useEffect(() => { if (currentText !== prevText) { setIsAnimating(true); setPrevText(currentText); const timer = setTimeout(() => setIsAnimating(false), 300); return () => clearTimeout(timer); } }, [currentText, prevText]); return ( <div className="status-bar-container"> <p className={`status-text ${isAnimating ? 'animating' : ''}`}> {currentText} </p> </div> ) }
对应SCSS样式
.status-text { transition: all 0.3s ease-in-out; opacity: 1; transform: scale(1); &.animating { opacity: 0; transform: scale(0.8); } }
内容的提问来源于stack exchange,提问作者Ilya Kruchinin
相关产品推荐
相关产品推荐

