React Transition Group无法触发enter/leave过渡效果问题求助
问题原因&修复方案
核心问题点
- Router 包裹范围错误,useLocation 调用非法:react-router 提供的
useLocation钩子必须在 Router 组件的子树内调用,才能获取到跟随路由跳转更新的 location 对象。你的代码中 Router 仅包裹了顶部导航栏,useLocation调用位置、以及承载路由匹配的 Switch 组件都在 Router 上下文范围外,导致拿到的 location 不会随路由跳转更新,CSSTransition 绑定的 key 没有变化,自然不会触发任何进入/离开的生命周期和过渡效果。 - 路由状态不连通:导航栏在 Router 内部,跳转的是 Router 内部的路由状态,外部的 Switch 和 TransitionGroup 完全感知不到路由变化,就会出现「组件能正常加载但没有过渡」的表现。
修复代码
你需要调整 Router 的位置,将所有用到路由相关能力的内容全部包裹在 Router 内部:
import * as React from 'react' import { HashRouter as Router, Link, Switch, Route, useLocation } from "react-router-dom"; import {TransitionGroup, CSSTransition} from "react-transition-group"; const TransGroup = () =>{ return( {/* 将Router移到最外层,包裹所有内容 */} <Router> <div className="w-full h-full"> <div className="fill w-full"> <ul className="nav overflow-hidden mb-8 flex "> <li><Link className="bg-white p-8 m-8 text-black inline-block" to="/">Red</Link></li> <li><Link className="bg-white p-8 m-8 text-black inline-block" to="/purple">Purple</Link></li> <li><Link className="bg-white p-8 m-8 text-black inline-block" to="/blue">Blue</Link></li> <li><Link className="bg-white p-8 m-8 text-black inline-block" to="/yellow">Yellow</Link></li> <li><Link className="bg-white p-8 m-8 text-black inline-block" to="/pink">Pink</Link></li> <li><Link className="bg-white p-8 m-8 text-black inline-block" to="/aqua">Aqua</Link></li> </ul> </div> {/* 把useLocation移到Router内部,可以拆成子组件,或者直接写在Router子树里 */} <RouteRender /> </div> </Router> ) } // 抽离路由渲染部分,确保useLocation在Router上下文内 const RouteRender = () => { const location = useLocation(); return ( <div className="fill content w-full h-full"> <TransitionGroup> <CSSTransition timeout={5000} onEnter={() => { console.log('FIRED!'); }} classNames={{ appear: 'my-node-appear', appearActive: 'my-node-active-appear', appearDone: 'my-node-done-appear', enter: 'my-node-enter', enterActive: 'my-node-active-enter', enterDone: 'my-node-done-enter', exit: 'my-node-exit', exitActive: 'my-node-active-exit', exitDone: 'my-node-done-exit', }} key={location.key} {/* 如需首次加载的过渡效果可以加上 appear 属性 */} // appear > <Switch location={location}> <Route exact path="/"> <div className="bg-red-500 text-white w-full h-16"> RED </div> </Route> <Route exact path="/purple"> <div className="bg-purple-500 text-white w-full h-16"> PURPLE </div> </Route> <Route exact path="/blue"> <div className="bg-blue-500 text-white w-full h-16"> BLUE </div> </Route> <Route exact path="/yellow"> <div className="bg-yellow-500 text-white w-full h-16"> YELLOW </div> </Route> <Route exact path="/pink"> <div className="bg-pink-500 text-black w-full h-16"> PINK </div> </Route> <Route exact path="/aqua"> <div className="bg-aqua-500 text-white w-full h-16"> AQUA </div> </Route> <Route path={'*'}> <div>Not Found</div> </Route> </Switch> </CSSTransition> </TransitionGroup> </div> ) } export default TransGroup
其他注意事项
你看到的弃用警告是因为 react-router-dom v6 已经废弃了 Switch 组件,替换为 Routes 组件,同时 exact 属性也已经移除,该警告不会导致过渡失效,如果你使用的是 v6 版本按官方文档调整路由写法即可。
内容的提问来源于stack exchange,提问作者cannon303
相关产品推荐
相关产品推荐

