使用 CSSTransitionGroup 和 React-Router v6 动画路由转换

Pre*_*fix 6 javascript reactjs react-router react-transition-group

我开始使用 React-Router v6,并且遇到了动画路由转换的问题。

无论是反应路由器文档反应过渡组文档指定不符合新的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>
  );
}
Run Code Online (Sandbox Code Playgroud)

...但是,在 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>
  );
}
Run Code Online (Sandbox Code Playgroud)

似乎主要的区别在于prop 的<Switch>接受程度Location,并且会保持两条路线的渲染时间足够长,以便转换结束。

没有它,路线入口动画似乎很突然。有趣的是,嵌套路由的退出动画似乎可以正常工作。

任何想法如何使用 react-router v6 获得过渡动画?

小智 12

看来您希望两个相应的组件同时出现在屏幕上;也就是说,新组件将以动画方式进入,而旧组件将以动画方式退出。

\n

在 v6.0.0-beta.3 之前这是不可能的。

\n

但现在(在 v6.0.0-beta.3 之后)由于将 prop 重新添加location到组件中而成为可能<Routes>。(v6.0.0-beta.3 的发行说明

\n

您的示例代码只需要进行 2 处修改即可适用于React-router@v6-beta.3 ,但需要对React-router@v6进行第 3 处修改:

\n
    \n
  1. <Router>应该改为网络兼容路由器,例如<BrowserRouter>.
  2. \n
  3. 该钩子必须路由器组件的上下文中useLocation()使用。要解决这个问题,您需要首先将路由器包装在父组件中,然后您才能在路由器的任何子组件中使用该钩子。
  4. \n
  5. 将 prop替换childrenelementprop,否则你会收到错误消息all component children of <Routes> must either be a <Route> or <React.Fragment>.
  6. \n
\n

\xe2\x80\x93 也有助于了解动画路线 - “默认<TransitionGroup>渲染 a<div> ” ,这有时会弄乱动画。所以对通过很有帮助component={null}因此,传递props 来阻止它这样做

\n

演示:所有这些更改都可以在此代码和框中找到:

\n

代码沙盒演示

\n

  • 感谢您的演示,太棒了!但知道如何仅对“Outlet”内容进行动画处理吗?假设我有一个带有“固定”部分的布局,该部分在所有页面上都可用。我分叉了[您的示例,并通过布局丰富了嵌套路由](https://codesandbox.io/s/animated-routes-outlet-demo-react-router-v6-h85sj)。 (2认同)