CSSTransition切换问题数组仅首次生效,后续无过渡效果求助
问题原因分析
你的CSSTransition组件把in属性绑定了currentQuestion这个数字状态,这是核心问题:
- 初始
currentQuestion=0,对应布尔值false,组件处于未激活状态 - 第一次切换到
currentQuestion=1时,in从false变true,触发进入动画 - 但后续切换(比如1→2、2→3)时,
currentQuestion始终是大于0的数字,对应布尔值true,in属性没有发生true↔false的状态切换,所以CSSTransition不会触发任何过渡动画
另外你现在只是替换同一个<Paragraph>的文本内容,没有让旧问题执行退出动画、新问题执行进入动画的流程,这也导致后续切换无动画。
解决方案
方案1:用TransitionGroup配合CSSTransition(推荐)
TransitionGroup会自动管理子元素的过渡,当子元素的key变化时,会触发旧元素的退出动画和新元素的进入动画:
import { TransitionGroup, CSSTransition } from 'react-transition-group'; // ... const [currentQuestion, setCurrentQuestion] = useState(0); // ... <div className={css.questionsContainer}> <TransitionGroup> <CSSTransition key={currentQuestion} classNames="alert" timeout={300} > <Paragraph large className={css.questions}> {internationalOnboardingQuestions[currentQuestion].questionText} </Paragraph> </CSSTransition> </TransitionGroup> </div>
方案2:单独维护过渡触发的布尔状态
如果不想用TransitionGroup,可以单独加一个状态控制in的切换,每次换题时先触发退出动画,再更新问题并触发进入动画:
const [currentQuestion, setCurrentQuestion] = useState(0); const [showQuestion, setShowQuestion] = useState(true); const handleNextQuestion = () => { // 先触发退出动画 setShowQuestion(false); // 等退出动画结束后更新问题,再触发进入动画 setTimeout(() => { setCurrentQuestion(prev => prev + 1); setShowQuestion(true); }, 300); // 时间要和timeout保持一致 }; // ... <div className={css.questionsContainer}> <CSSTransition in={showQuestion} classNames="alert" timeout={300} unmountOnExit > <Paragraph large className={css.questions}> {internationalOnboardingQuestions[currentQuestion].questionText} </Paragraph> </CSSTransition> </div>
补充:修复CSS细节
你CSS里alert-enter-active的transform: translateX(0)和初始状态的scale(0.9)不匹配,建议改成一致的变换类型,避免动画突兀:
.alert-enter { opacity: 0; transform: scale(0.9); } .alert-enter-active { opacity: 1; transform: scale(1); /* 和初始状态的scale对应 */ transition: opacity 300ms, transform 300ms; }
内容的提问来源于stack exchange,提问作者boogiehsows
相关产品推荐
相关产品推荐

