React Transition Group结合Router时离开动画不生效的解决方法求助
解决React TransitionGroup路由切换时离开动画不生效的问题
我之前也碰到过一模一样的问题!直接把<Route>放在<TransitionGroup>里是行不通的——因为路由切换时,匹配旧路径的Route会被React Router立刻从DOM中移除,TransitionGroup根本没机会捕捉到它的“离开”状态,自然触发不了退出动画。
核心问题分析
React Router的<Route>在路径不匹配时会直接卸载对应组件,而<TransitionGroup>需要组件在DOM中保留足够长时间来完成退出动画。所以我们需要给组件一个“缓冲期”,让TransitionGroup能管理它的进入和退出流程。
修复方案
我们需要调整组件结构,用<CSSTransition>(或<Transition>)包裹路由的渲染结果,并基于当前路由路径设置唯一的key,同时配合withRouter来获取路由状态。
1. 调整代码结构
import { TransitionGroup, CSSTransition } from 'react-transition-group'; import { Switch, Route, withRouter } from 'react-router-dom'; class App extends React.Component { render() { // 通过withRouter注入location对象 const { location } = this.props; return ( <TransitionGroup> {/* 用当前路由路径作为key,确保路由切换时触发组件替换 */} <CSSTransition key={location.pathname} timeout={500} // 要和CSS过渡时长一致 classNames="fade" // 对应CSS中的类前缀 unmountOnExit // 动画完成后自动卸载组件 > {/* 把Switch放在CSSTransition内部,传递location确保路由匹配正确 */} <Switch location={location}> <Route exact path="/" component={Home} /> <Route exact path="/about" component={About} /> </Switch> </CSSTransition> </TransitionGroup> ); } } // 用withRouter包裹组件,获取路由相关的props export default withRouter(App);
2. 完善动画CSS
确保你的CSS中包含了完整的过渡类:
/* 进入动画初始状态 */ .fade-enter { opacity: 0; } /* 进入动画活跃状态 */ .fade-enter-active { opacity: 1; transition: opacity 500ms ease-in; } /* 退出动画初始状态 */ .fade-exit { opacity: 1; } /* 退出动画活跃状态 */ .fade-exit-active { opacity: 0; transition: opacity 500ms ease-out; }
为什么这样能解决问题?
key={location.pathname}:每次路由切换时,这个key都会变化,TransitionGroup会识别到“旧组件需要退出,新组件需要进入”,从而触发对应的动画。- 传递
location给Switch:确保Switch始终基于当前的路由状态渲染,不会因为TransitionGroup的切换延迟导致路由匹配错误。 unmountOnExit:在退出动画完成后自动卸载旧组件,避免DOM中残留无用的组件节点。
额外注意事项
- 确保你使用的是
react-transition-groupv2及以上版本,旧版本的API和现在差异很大。 timeout的数值必须和CSS中transition的时长完全一致,否则TransitionGroup会提前结束动画或延迟卸载组件。
内容的提问来源于stack exchange,提问作者jeankvd
相关产品推荐
相关产品推荐

