react-transition-group中CSSTransition退出动画失效问题求助
解决CSSTransition退出动画失效及onExited钩子未触发问题
嘿,我帮你找出问题所在啦!你的CSSTransition退出动画失效、onExited(你代码里不小心写成onExied了,记得修正哦)钩子没触发,主要是classNames的配置逻辑没贴合组件的生命周期规则,加上退出阶段的样式衔接错误,导致过渡动画根本没触发。咱们一步步来修正:
一、先理清CSSTransition的类名生命周期逻辑
CSSTransition会在不同阶段给元素添加对应的类名,咱们需要让这些类名对应正确的样式状态,才能触发过渡:
- 进入/首次挂载:
appear→appear-active→appear-done/enter-done - 退出:
exit→exit-active→exit-done(之后组件卸载,因为你开了unmountOnExit)
你的原始配置里,退出阶段的起始状态没衔接上进入完成后的激活状态,所以没有过渡的“起点”,自然不会有动画。
二、修正CSS样式
先把样式调整得更清晰,区分基础状态和激活状态:
/* 基础隐藏状态:默认在视口外 */ .getSecondLevelPanel { position: fixed; left: 450px; top: -100%; height: 100%; width: 400px; transition: all 250ms ease-out; } /* 激活显示状态:固定在顶部 */ .getSecondLevelPanel--opened { top: 0; }
三、修正React组件的CSSTransition配置
重点调整classNames的映射,确保每个阶段的样式正确衔接,同时修正小细节:
import * as React from 'react'; import { CSSTransition } from 'react-transition-group'; export interface Props { isVisible: boolean; // 这里把Boolean改成boolean,TS里原始类型用小写 children: React.ReactChild; onClose: () => void; } const SecondLevelPanel = (props: Props) => { return ( <CSSTransition timeout={{ enter: 250, exit: 250 }} // 和CSS过渡时间保持一致,确保钩子触发时机正确 in={props.isVisible} appear={true} enter={true} exit={true} classNames={{ // 首次挂载/进入的起始状态:隐藏 appear: 'getSecondLevelPanel', enter: 'getSecondLevelPanel', // 进入动画过程:切换到激活状态,触发过渡 appearActive: 'getSecondLevelPanel getSecondLevelPanel--opened', enterActive: 'getSecondLevelPanel getSecondLevelPanel--opened', // 进入完成后保持激活状态 enterDone: 'getSecondLevelPanel getSecondLevelPanel--opened', // 退出起始状态:保持激活状态(从top:0开始) exit: 'getSecondLevelPanel getSecondLevelPanel--opened', // 退出动画过程:切回隐藏状态,触发过渡 exitActive: 'getSecondLevelPanel' }} unmountOnExit={true} onEntered={() => { alert('entered'); }} onExited={() => { // 这里修正了拼写错误 alert('exited'); }} > {/* 给内容加个容器,避免样式冲突 */} <div className="second-level-panel-content"> <a onClick={() => props.onClose()}>Close</a> {props.children} </div> </CSSTransition> ); }; export default SecondLevelPanel;
四、关键修正点说明
- classNames的正确衔接:
- 退出阶段的
exit类必须包含激活状态(getSecondLevelPanel--opened),这样动画才会从top:0的状态开始过渡到top:-100%。 exitActive类切换回基础隐藏状态,触发CSS过渡动画。
- 退出阶段的
- timeout与CSS过渡时间匹配:把
exit的timeout改成250ms,和CSS里的过渡时长一致,确保动画完全结束后才触发onExited钩子并卸载组件。 - TS类型修正:把
Props里的Boolean改成boolean,符合TypeScript的类型规范。 - 拼写修正:把
onExied改成正确的onExited,不然钩子肯定不会触发😅。
现在你再测试一下,点击Close按钮后,面板会平滑地滑出视口,动画结束后onExited的alert会弹出,组件也会正常卸载啦!
内容的提问来源于stack exchange,提问作者podeig
相关产品推荐
相关产品推荐

