使用 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:

  1. <Router> 应该改为 web 兼容路由器,例如 <BrowserRouter>.
  2. 必须在路由器组件的上下文中使用useLocation()挂钩。要解决这个问题,您需要先将路由器包裹在父组件中,然后您才能在路由器的任何子组件中使用挂钩。
  3. children 属性替换为 element 属性,否则会出现 all component children of <Routes> must either be a <Route> or <React.Fragment>.
  4. 错误

另外 – 了解动画路线很有帮助 – "<TransitionGroup> renders a <div> by default" 有时会弄乱动画。所以在道具中传递 component={null} 以阻止它这样做是有帮助的。

DEMO:所有这些更改都可以在 codesandbox:

中找到

与此同时,此问题已得到解决。 这里提到了这个问题 here

在此处查看工作代码示例:here