使用 CSSTransitionGroup 和 React-Router v6 动画路由转换
Animating route transitions with CSSTransitionGroup and React-Router v6
我开始使用 React-Router v6,并且 运行 解决动画路由转换的问题。
react-router docs and the 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 一起工作吗?
react-router-v6 发生了变化。阅读 here and here
要让您的动画正常运行,请将 Switch
替换为 Routes
(无需提供位置)。向 Route
提供 element
道具。同时安装 history
库。
我已经使用 v6 制作了一个工作演示。进入和离开动画都在工作。将代码与您的进行比较。
您似乎希望两个组件同时显示在屏幕上;也就是说,新组件将以动画方式进入,而旧组件将以动画方式退出。
在 v6.0.0-beta.3 之前这是不可能的。
但现在可以(在 v6.0.0-beta.3 之后),这要归功于将 location
属性重新添加到 <Routes>
零件。 (release notes for v6.0.0-beta.3)
您的示例代码只需要 2 次修改即可用于 react-router@v6-beta.3,但需要第 3 次修改才能用于 react-router @v6:
<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" 有时会弄乱动画。所以在道具中传递 component={null}
以阻止它这样做是有帮助的。
DEMO:所有这些更改都可以在 codesandbox:
中找到
与此同时,此问题已得到解决。
这里提到了这个问题 here。
在此处查看工作代码示例:here。
我开始使用 React-Router v6,并且 运行 解决动画路由转换的问题。
react-router docs and the 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 一起工作吗?
react-router-v6 发生了变化。阅读 here and here
要让您的动画正常运行,请将 Switch
替换为 Routes
(无需提供位置)。向 Route
提供 element
道具。同时安装 history
库。
我已经使用 v6 制作了一个工作演示。进入和离开动画都在工作。将代码与您的进行比较。
您似乎希望两个组件同时显示在屏幕上;也就是说,新组件将以动画方式进入,而旧组件将以动画方式退出。
在 v6.0.0-beta.3 之前这是不可能的。
但现在可以(在 v6.0.0-beta.3 之后),这要归功于将 location
属性重新添加到 <Routes>
零件。 (release notes for v6.0.0-beta.3)
您的示例代码只需要 2 次修改即可用于 react-router@v6-beta.3,但需要第 3 次修改才能用于 react-router @v6:
<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" 有时会弄乱动画。所以在道具中传递 component={null}
以阻止它这样做是有帮助的。
DEMO:所有这些更改都可以在 codesandbox:
中找到与此同时,此问题已得到解决。 这里提到了这个问题 here。
在此处查看工作代码示例:here。