如何正确配置react-transition-group实现嵌套路由独立动画?
解决React Router嵌套路由动画被外层覆盖的问题
这个问题不是react-transition-group不支持嵌套路由动画,而是你的动画作用范围和CSS优先级导致的冲突——外层的CSSTransition把整个嵌套组件都包裹在了它的fade动画容器里,当路由切换时,外层的fade动画会先触发,并且它的CSS规则会覆盖内层zoom动画的样式。下面给你两种可行的解决方案:
方案1:给顶层路由单独添加动画(推荐)
不要用CSSTransition包裹整个外层Switch,而是给每个顶层路由的组件单独包裹CSSTransition。这样外层动画只会作用于顶层路由的内容,嵌套路由的动画容器是独立的,不会被覆盖:
import { useLocation, Switch, Route, NavLink } from "react-router-dom"; import { CSSTransition } from "react-transition-group"; function AnimationApp() { const location = useLocation(); return ( <div className="app-container"> <nav> <NavLink to="/">Home</NavLink> <NavLink to="/nested">Nested Routes</NavLink> </nav> <Switch location={location}> {/* 给每个顶层路由单独加fade动画 */} <Route path="/nested"> <CSSTransition key={location.key} classNames="fade" timeout={500}> <Nested /> </CSSTransition> </Route> <Route path="/"> <CSSTransition key={location.key} classNames="fade" timeout={500}> <Home /> </CSSTransition> </Route> </Switch> </div> ); } function Nested() { const location = useLocation(); return ( <div className="nested-container"> <nav> <NavLink to="/nested/sub1">Sub Page 1</NavLink> <NavLink to="/nested/sub2">Sub Page 2</NavLink> </nav> {/* 嵌套路由的zoom动画正常使用 */} <CSSTransition key={location.key} classNames="zoom" timeout={500}> <Switch location={location}> <Route path="/nested/sub1"> <SubPage title="Sub Page 1" /> </Route> <Route path="/nested/sub2"> <SubPage title="Sub Page 2" /> </Route> <Route path="/nested"> <NestedHome /> </Route> </Switch> </CSSTransition> </div> ); }
方案2:提高嵌套动画的CSS优先级
如果你坚持要在外层用CSSTransition包裹整个Switch,可以通过增强嵌套动画CSS选择器的优先级来覆盖外层样式:
/* 外层fade动画样式 */ .fade-enter { opacity: 0; } .fade-enter-active { opacity: 1; transition: opacity 500ms; } .fade-exit { opacity: 1; } .fade-exit-active { opacity: 0; transition: opacity 500ms; } /* 嵌套zoom动画样式,通过父容器选择器提高优先级 */ .nested-container .zoom-enter { transform: scale(0.9); opacity: 0; } .nested-container .zoom-enter-active { transform: scale(1); opacity: 1; transition: transform 500ms, opacity 500ms; } .nested-container .zoom-exit { transform: scale(1); opacity: 1; } .nested-container .zoom-exit-active { transform: scale(0.9); opacity: 0; transition: transform 500ms, opacity 500ms; }
这种方法虽然可行,但不如第一种方法清晰,容易引发后续的CSS优先级问题,所以更推荐方案1。
总结一下:react-transition-group完全支持嵌套路由动画,你的问题是动画作用范围的设计导致的样式覆盖,调整动画的包裹范围或者CSS优先级就能解决。
内容的提问来源于stack exchange,提问作者Laurence Fass
相关产品推荐
相关产品推荐

