首页 文章

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

提问于
浏览
3

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

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

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

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

简而言之,我相信我需要一种单独动画路线的方法而不是典型的"transition between routes" . 例如,在 //foo 之间导航应该产生以下结果:

  • / 上,导航到 /foo - > Foo 组件动画 .

  • /foo 上,导航到其他任何地方,例如 / - > Foo 组件动画 .

我希望这是有道理的,谢谢!

1 回答

  • 4

    也许,你可以延迟过渡,以便完成“离开”动画

    1) with 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>
        );
      }
    }
    

相关问题