使用react-router为各个路由设置动画

时间:2016-07-12 03:40:19

标签: javascript reactjs react-router

我使用的是react-router,我希望能够在安装和卸载时渲染和转换任意组件。现在我已将组件添加到我的路径定义中:

<Route component={App}>
    <Route
      path="foo"
      component={Foo}
    />
    <Route
      path="bar"
      component={Bar}
    />
</Route>

我在组件中使用react css过渡组在进入和离开时为它们设置动画。这些组件在进入时会安装和动画。但是当我离开路线时,立即移除渲染的组件,因此没有留下动画。

典型的解决方案是将转换组添加到父级,以便它不会卸载,并从中为子级设置动画。这对我不起作用,因为Foo组件和Bar组件使用完全不同的动画。

简而言之,我认为我需要一种方法来单独设置路线动画,而不是路线之间的典型转换&#34;。例如,在//foo之间导航应该会产生以下结果:

  1. 登录/,导航至/foo - &gt; Foo组件动画。
  2. 登录/foo,导航到其他任何地方,例如/ - &gt; Foo组件动画化。
  3. 我希望这是有道理的,谢谢!

1 个答案:

答案 0 :(得分:4)

也许,你可以延迟过渡,以便完成&#34;离开&#34;动画

1)使用onChange jsfiddle示例:https://jsfiddle.net/qnpj0odc/7/

const func = ({location:{pathname:prev}}, nextState, replace, callback)=>{
    prev=="/foo" ? setTimeout(callback,3000)
    :prev=="/bar" ? setTimeout(callback,2000)
    :callback();
};

<Route  path="/" component={App} onChange={func}>
    <Route path="foo" component={Foo} />
    <Route path="bar" component={Bar} />
</Route>

enter image description here

2)with setRouteLeaveHook https://jsfiddle.net/qnpj0odc/24/

class Foo extends React.Component{
  constructor(props){
    super(props);
    this.state={leave:0};
    props.router.setRouteLeaveHook(props.route,n=>this.startAnim(n))
  }
  startAnim(next){
    this.setState({leave:1});
    setTimeout(()=>{
      this.allow=1;
      this.props.router.push(next.pathname);},500)
    return !!this.allow;
  }
  render(){
    return (
        <h1 className={"animated zoomIn"+(this.state.leave?" zoomOut ":"")}>FOO</h1>
    );
  }
}

3)with listenBefore https://jsfiddle.net/qnpj0odc/23/

class Foo extends React.Component{
  constructor(props){
     super(props);
     this.state={leave:0};
     this.cb = props.router.listenBefore((loc,cb)=>{
       loc.pathname == props.location.pathname ?
       this.setState({leave:0}) :
       this.setState({leave:1},()=>setTimeout(cb,500))});
  }
  componentWillUnmount(){
    this.cb(); //unlisten
  }
  render(){
    return (
        <h1 className={"animated zoomIn"+(this.state.leave?" zoomOut ":"")}>FOO</h1>
    );
  }
}