Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React router 4 beta 2 with ReactCSSTransitionGroup

I prefer ReactCSSTransitionGroup for react-motion. The below code causes the component to fade in (appear) on route change, BUT the issue is - the leaving component does not fade out, it leaves instantly.

<Switch>
    <FadeRoute exact path="/" component={PageLanding}/>
    <FadeRoute path="/login" component={PageLogin}/>
    <FadeRoute path="/signup" component={PageSignup}/>
    <FadeRoute component={Page404}/>
</Switch>

function FadeRoute({component:Component, ...rest}) {
    return (
        <Route {...rest} children={({location,match}) => (
                <ReactCSSTransitionGroup {...{key:Date.now(), transitionName:'fade', transitionAppear:true, transitionEnter:true, transitionLeave:true, transitionAppearTimeout:300, transitionEnterTimeout:300, transitionLeaveTimeout:300})}>
                    <Component/>
                </ReactCSSTransitionGroup>
        )} />
    );
}
<style>
.fade-enter, .fade-appear { opacity:0; }
.fade-enter.fade-enter-active,
.fade-appear.fade-appear-active { opacity:1; transition: opacity 300ms; }
.fade-leave { opacity:1; }
.fade-leave.fade-leave-active { opacity:0; transition: opacity 300ms; }
</style>
like image 389
Noitidart Avatar asked Dec 10 '22 13:12

Noitidart


1 Answers

The way that a <Switch> works is that it only renders the first <Route> whose path is matched by the current location. This means that when you navigate, the existing <FadeRoute> is immediately unmounted when you navigate. Its child <CSSTransitionGroup> is also unmounted, so it has no opportunity to run the leave transition for its children.

What you want to do is to wrap your <Switch> in a <CSSTransitionGroup>. The <Switch> is the component that will be transitioned, so it should have a key. You should also pass it the location object so that when a <Switch> is leaving, it animates using the old location instead of the current one.

<CSSTransitionGroup
  transitionName='fade'
  transitionEnterTimeout={500}
  transitionLeaveTimeout={500}
>
  <Switch key={location.pathname} location={location}>
    <Route path="/red" render={Red} />
    <Route path="/green" render={Green} />
    <Route path="/blue" render={Blue} />
  </Switch>
</CSSTransitionGroup>
like image 111
Paul S Avatar answered Jan 12 '23 17:01

Paul S