使用 CSSTransitionGroup 和 React-Router v6 动画路由过渡
Posted
技术标签:
【中文标题】使用 CSSTransitionGroup 和 React-Router v6 动画路由过渡【英文标题】:Animating route transitions with CSSTransitionGroup and React-Router v6 【发布时间】:2020-07-20 04:16:18 【问题描述】:我开始使用 React-Router v6,并遇到了动画路由转换的问题。
react-router docs 和react-transition-group docs 都指定了与新 v6 api 不兼容的方式。
主要原因似乎是删除了<Switch>
组件。
在 react-router@v5 中,这有效:
import Router, Route, Switch, useLocation from 'react-router@v5'
import TransitionGroup, CSSTransition from 'react-transition-group'
function App()
const location = useLocation();
return (
<Router>
<TransitionGroup>
<CSSTransition key=location.key classNames="fade" timeout=300>
<Switch location=location>
<Route path="/a" children=<A /> />
<Route path="/b" children=<B /> />
</Switch>
</CSSTransition>
</TransitionGroup>
</Router>
);
...但是,在 react-router@v6 中,这不起作用:
function App()
const location = useLocation();
return (
<Router>
<TransitionGroup>
<CSSTransition key=location.key classNames="fade" timeout=300>
<Routes location=location>
<Route path="/a" element=<A /> />
<Route path="/b" element=<B /> />
</Routes>
</CSSTransition>
</TransitionGroup>
</Router>
);
似乎主要区别在于<Switch>
接受Location
属性的方式,并将保持两条路由渲染足够长的时间以完成转换。
没有它,似乎路线入口动画很突然。有趣的是,嵌套路由的退出动画似乎可以正常工作。
任何想法如何使用 react-router v6 获得过渡动画?
【问题讨论】:
【参考方案1】:您似乎希望同时在屏幕上显示两个相应的组件;也就是说,新组件将在旧组件动画输出时进行动画处理。
在 v6.0.0-beta.3 之前这是不可能的。
但现在可以(在 v6.0.0-beta.3 之后)感谢将 location
属性重新添加到 <Routes>
组件。 (release notes for v6.0.0-beta.3)
您的示例代码只需要对 react-router@v6-beta.3 进行 2 次修改,但需要对 react-router@v6 进行第 3 次修改:
<Router>
应该改为 Web 兼容路由器,例如 <BrowserRouter>
。
useLocation()
挂钩必须在 路由器组件的上下文中使用。要解决这个问题,您需要先将路由器包裹在父组件中,然后才能在路由器的任何子组件中使用挂钩。
将children
属性替换为element
属性,否则会出现all component children of <Routes> must either be a <Route> or <React.Fragment>.
错误
另外 - 有助于了解动画路线 - "<TransitionGroup>
renders a <div>
by default" 有时会与动画混淆。因此,在 props 中传递 component=null
以阻止它这样做会很有帮助。
DEMO:所有这些更改都可在此codesandbox:
中找到【讨论】:
感谢您的演示,非常棒!但是知道如何只为Outlet
内容制作动画吗?假设我有一个在所有页面上都可用的带有“固定”部分的布局。我分叉了your example and enriched with nested routes with a layout。【参考方案2】:
react-router-v6 发生了变化。阅读here和here
要使您的动画正常工作,请将 Switch
替换为 Routes
(无需提供位置)。将element
属性提供给Route
。同时安装history
库。
我使用 v6 做了一个工作演示。进入和离开动画都在工作。将代码与您的代码进行比较。
【讨论】:
这个还是有问题的。如果您在示例中注意到,在转换时,出去的 Route 将更改为进来的新 Route。在 v5 中情况并非如此,因为您可以传入一个允许 Route 去和 Route 进来的 location 道具代表他们的正确路线,而不仅仅是活动的。有关此特定问题的活动线程,请参阅 here。【参考方案3】:与此同时,此问题已得到修复。 这里提到了这个问题here。
在此处查看工作代码示例:here。
【讨论】:
以上是关于使用 CSSTransitionGroup 和 React-Router v6 动画路由过渡的主要内容,如果未能解决你的问题,请参考以下文章
TransitionGroup 和 CssTransition:未应用退出过渡
React Transition Group:偏移动画开始时间