美文网首页
React 路由切换动画

React 路由切换动画

作者: 薛定谔的程序 | 来源:发表于2021-02-02 22:12 被阅读0次

    环境 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 文档提供的示例

    效果


    屏幕录制2021-02-02 下午10.gif

    动画执行

    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");时
    [图片上传失败...(image-9ff118-1612605579556)]
    可以看到虽然就是当前路由页面也没有变化不过location对象发生变化了,变化的就是key属性
    每次的都不一样,所以用location.key当key会导致这样一个画面

    屏幕录制2021-02-06-下午3.11.01.gif
    一直跳转当前路由带来的是组件的不断创建销毁,呸
    解决: 控制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定位,也不绝对

    相关文章

      网友评论

          本文标题:React 路由切换动画

          本文链接:https://www.haomeiwen.com/subject/gksutltx.html