react-router4路由切换动画

写在前面

之前我写过关于react-transition-groupreact-motion的使用教程,就控制粒度上来说,react-motion要好很多,但是react-motion有个比较麻烦的问题,就是我暂时没找到开箱即用的动画封装,而用react-motion也没法使用animate.css,所以如果项目仅仅只用于web端,没考虑native,那么建议还是使用react-transition-group,会方便很多

用到的第三方库

  • react-router-dom 4.2.2 用于路由
  • react-transition-group 2.2.1 用于react动画实现,这里需要注意下,使用的不是版本1,而是只包含{Transition, TransitionGroup, CSSTransition}的版本2
  • animate.css 用于动画效果

热身

在正式开始写路由的切换动画前,我们先用react-transition-group结合animate.css来实现一个简单的组件进出场动画,以此回顾之前关于react-transition-group的知识
react-transition-group文档

    
{/*第一个例子*/}

效果

react-router4路由切换动画_第1张图片
demo1.gif

代码很简单,用 in控制组件的显示和隐藏,用 classNames控制组件进出场的className,稍微需要注意的是与 animate.css的结合方式

路由切换

回顾了组件的进场和出场动画实现后,我们正式来开始写路由的切换动画。先理清楚思路,在react-router4里面,每个路由对应其实就是一个组件,无非就是在路由匹配到的时候,将CSSTransitionin设置为true,不匹配设置为false,仅此而已。
唯一麻烦的地方在于怎么获取路由的匹配信息,翻看react-router4的api,我们看到,Route和渲染有关的props有三个,component,render,children,componentrender都拿不到匹配信息,只要路由匹配到,组件就会mount,反之,就会unmount,我们无法进行控制,而children正好符合我们的期望,它与render类似,不同的地方在于无论path是否匹配,都会被触发,然后会将当前的match信息传递过来,我们也正好可以通过match来控制CSSTransition

先写一个无动画的路由切换

不管怎么样,我们先写个简单的路由切换,然后再对其进行改装

主路由


        
home page1 page2
{ if(!props.match) return null return }} /> { if(!props.match) return null return }} /> { if(!props.match) return null return }} />

Index

class Index extends Component {
    render() {
      return 
index
} }

Page1

class Page1 extends Component {
    render() {
      return 
page1
} }

Page2

class Page2 extends Component {
    render() {
      return 
page2
} }

简单的路由就写好了,接下来考虑加动画

利用高阶组件给页面加上动画

我并不希望在页面内部实现动画逻辑,首先是页面逻辑与动画逻辑无关,其次如果每写一个页面就写一次动画逻辑,我怕是要累死,所以我们这里将动画逻辑单独抽取出来,封装成一个高阶组件

function wrapAnimation(WrappedComponent) {
  return class extends Component {
    render() {
      return (
        
          
        
      )
    }
  }
}

也是没啥可讲的代码,接下来,我们将我们的页面Index, Page1, Page2外面套一层高阶组件

const Index = wrapAnimation(
  class Index extends Component {
    render() {
      return 
index
} } ) const Page1 = wrapAnimation( class Page1 extends Component { render() { return
page1
} } ) const Page2 = wrapAnimation( class Page2 extends Component { render() { return
page2
} } )

ok,然后再稍微修改下我们的路由层


        
home page1 page2
{ return }} /> { return }} /> { return }} />

接下来,直接看效果吧


react-router4路由切换动画_第2张图片
router4-transition.gif

总结

和普通的组件切换动画差不多,只是需要注意下怎么在react-router4的路由中获取组件的显示状态

完整的代码我放到了github上: https://github.com/soyal/router4-transition

感谢你的阅读

你可能感兴趣的:(react-router4路由切换动画)