环境 create-react-app
yarn add “react-transition-group”: “^4.4.1”,
“react”: “^17.0.1”
“react-router-dom”: “^5.2.0”,

​react-transition-group​

​react-router 文档提供的示例​

效果

React 路由切换动画_reactjs


动画执行

import { CSSTransition, TransitionGroup } from "react-transition-group";
// jsx
<TransitionGroup>
<CSSTransition key={location.pathname} classNames="fade" timeout={300}>
<Switch>
<Route xxxx />
</Switch>
</CSSTransition>
</TransitionGroup>
小bug 当前路径跳转自己
当前路由跳转自己,一直执行动画组件刷新,正常跳转路径是当前路径是不需要变动的,默认的​​NavLink​​跳转自己也是没有变化de
需要注意的就是​​<CSSTransition key={location.pathname} ...​​​的​​key​​属性
这个key属性,react-router-dom给的示例用的是​​location.key​​,我直接复制就出现了这个问题
key的意思当然就是辨识唯一,如果key不同,动画执行,key相同,不执行动画
而​​location.key​​会随机产生,即便跳转的是当前路由
当执行 replace(“dashboard”);时

React 路由切换动画_css_02


可以看到虽然就是当前路由页面也没有变化不过​

​location​

​对象发生变化了,变化的就是​

​key​

​属性


每次的都不一样,所以用location.key当key会导致这样一个画面


React 路由切换动画_css_03


一直跳转当前路由带来的是组件的不断创建销毁,呸


解决: 控制key不变就可以了,简单处理就是使用llocation.pathname`上面问题就可以解决,


复杂的可以用location.hash 和search配合尝试,还没遇到

示例:
路由父组件

要执行动画组件最外层必须是absolute定位最好是放一个div,父级relative固定下

import { Layout } from "antd";
const Content = styled(Layout.Content)`
position: relative;
margin: 10px;
padding: 0;
display: flex;
`;
// jsx
<StyledContent>
<TransitionRoute routes={routes} />
</StyledContent>

动画组件
​​​TransitionRoute.tsx​

import React from "react";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { Route, Switch, useLocation } from "react-router-dom";
import { IRoute } from "../type";
import "./TransitionStyle.css";

interface TransitionRouteProps {
routes: Array<IRoute>;
}

const renderRoute = ({ path, Component }: IRoute) => (
<Route key={path} path={path} component={Component}></Route>
);

const TransitionRoute: React.FC<TransitionRouteProps> = ({ routes }): any => {
const location = useLocation();

return (
<TransitionGroup>
<CSSTransition key={location.pathname} classNames="fade" timeout={300}>
<Switch location={location}>{routes.map(renderRoute)}</Switch>
</CSSTransition>
</TransitionGroup>
);
};

export default TransitionRoute;

​css文件​

.page-enter {
opacity: 0;
transform: scale(1.1);
}

.page-enter-active {
opacity: 1;
transform: scale(1);
transition: opacity 300ms, transform 300ms;
}

.page-exit {
opacity: 1;
transform: scale(1);
}

.page-exit-active {
opacity: 0;
transform: scale(0.9);
transition: opacity 300ms, transform 300ms;
}
/* .fade-enter {
opacity: 0;
z-index: 1;
}

.fade-enter.fade-enter-active {
opacity: 1;
transition: opacity 250ms ease-in;
} */
.fade-enter {
opacity: 0;
z-index: 1;
left: 100% !important;
}

.fade-enter.fade-enter-active {
opacity: 1;
left: 0 !important;
transition: all 300ms ease-in;
}

.fade-exit {
opacity: 1;
}

.fade-exit-active {
opacity: 0;
transition: opacity 300ms ease-in;
/* transition: opacity 300ms, transform 300ms; */
}

需要注意路由组件最外层absolute定位,也不绝对