Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

配置路由下如何实现路由动画 #4827

Closed
wansuiasdn opened this issue Jun 3, 2020 · 8 comments
Closed

配置路由下如何实现路由动画 #4827

wansuiasdn opened this issue Jun 3, 2020 · 8 comments

Comments

@wansuiasdn
Copy link

无论是ant-motion还是react-transition-group都是需要在页面内重写路由的,配置路由的情况下如何实现,求赐教啊。

@CJY0208
Copy link
Member

CJY0208 commented Jun 10, 2020

@anakornk
Copy link

anakornk commented Jun 21, 2020

遇到同样的问题,花了点时间去读源码。上面那篇文章是针对于 v2,在v3会有点问题。

layout 组件的 children props 是 Switch 组件。v2 中直接使用 react-router的 switch 组件,该组件使用的location 是通过props 传进来。v3 中的switch 是对 react-router 进行了包装, location 是从router context 获取的。

v2

<Layout>
  <Switch location={}>
    <Route ...>
    <Route ...>
    <Route ...>
  </Switch>
</Layout>

v3

<Layout>
  <Switch> // custom switch
    <Route ...>
    <Route ...>
    <Route ...>
  </Switch>
</Layout>

我暂时的解决方法是读取 switch 的 props, 用react-router 重新建 switch 组件,并把 location 传进去。

  // layout/index.tsx

  const newSwitch = (
    <Switch location={location}>{children.props.children}</Switch>
  );

  // Example using React-Transition-Group
  
  return (
    <TransitionGroup
      childFactory={(child: any) =>
        React.cloneElement(child, {
          classNames: 'forward',
        })
      }
    >
      <CSSTransition key={location.pathname} timeout={2000}>
        {newSwitch}
      </CSSTransition>
    </TransitionGroup>
  );

完整 demo (通过React Transition Group 和 React-Spring):
https://github.com/TongHuaLabs/umi-page-animation

参考文献:

@anakornk
Copy link

anakornk commented Jun 21, 2020

比较了一下Umi Switch 和 react-router Switch, 两个主要区别是 Umi Switch 允许通过 cloneElement 的方式传递参数给子路由 ( 参考: https://umijs.org/docs/routing#传递参数给子路由 ), 以及location 只能通过 Router Context 获取。

@sorrycc , 能否允许和react-router Switch一样通过传递 location props 来配置 Switch?

// https://github.com/umijs/umi/blob/master/packages/renderer-react/src/renderRoutes/Switch.tsx
// line 9
const location = props.location || context.location;

这样就可以通过 cloneElement 传递 location 实现路由动画,以及传递其他参数给子路由

  const newChildren = React.cloneElement(children, {
    location,
    something: 'helloworld',
  });

参考文献:

@wansuiasdn
Copy link
Author

@anakornk 感谢大佬,按您的demo写了一下,但是我这有一个问题,就是A页面和B页面公用了一套封装好的layout,当A跳转到B时,动画效果‘fade’并不是A渐隐B出现,而是B页面渐隐B页面出现,也就是说组件在路由跳转的时候就已经被更新了A页面直接变成了B页面,然后才播放路由动画,您有遇到过这种问题么

@anakornk
Copy link

anakornk commented Jul 7, 2020

@anakornk 感谢大佬,按您的demo写了一下,但是我这有一个问题,就是A页面和B页面公用了一套封装好的layout,当A跳转到B时,动画效果‘fade’并不是A渐隐B出现,而是B页面渐隐B页面出现,也就是说组件在路由跳转的时候就已经被更新了A页面直接变成了B页面,然后才播放路由动画,您有遇到过这种问题么

layout 里面import的switch是从react-router 引来的吗?还有记得把location props 传进去。

import { Switch } from 'react-router';

@wansuiasdn
Copy link
Author

wansuiasdn commented Jul 8, 2020

@anakornk
贴下我的代码

import { TransitionGroup, CSSTransition } from 'react-transition-group';
import { withRouter } from 'umi';
import React from 'react'
import { Switch } from 'react-router'
export default withRouter(({ location, children, history }) => {

const newSwitch = (
    <Switch location={location}>{children.props.children}</Switch>
);

return (
    <TransitionGroup childFactory={child => React.cloneElement(child, { classNames: 'forward' })}>
        <CSSTransition key={location.pathname} timeout={2000}>
            {newSwitch}
        </CSSTransition>
    </TransitionGroup>

);

});

@xclw2000
Copy link

我遇到了和 @wansuiasdn ``同样的问题,不过,我是因为嵌套了两层Layout,才出现的问题。

export default [
  {
    path: '/',
    component: '@/layouts/TransitionLayout',
    routes: [
      {
        path: '/',
        component: '@/layouts/SecurityLayout',
        routes: [
          { path: '/', component: '@/pages/home', exact: true },
          { path: '/hello', component: '@/pages/hello', exact: true },
          { path: '/world', component: '@/pages/world', exact: true },
        ],
      },
    ],
  },
];

第一层Layout就是@anakornk的源码中的layouts/index, 第二层layout是自己的业务逻辑代码

@wansuiasdn
Copy link
Author

@xclw2000 大佬这个问题解决了么?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants