I have to exclude one Route from transition group. Given below the code
<Route
render={({ location }) => (
<div className="App">
<TransitionGroup className="transition-item">
<CSSTransition
key={location.key}
timeout={300}
classNames="fade"
>
<Switch location={location}>
<Route
path="/login"
exact
render={routeProps => (<LoginPage {...routeProps} />)}
/>
<Route
path="/logout"
exact
render={(routeProps: any) => (<LogoutPage {...routeProps} />)}
/>
<PrivateRoute
path="/"
exact
render={(routeProps: any) => <HomePage />}
/>
<PrivateRoute
path="/profile"
exact
render={(routeProps: any) => (<Profile {...routeProps} />)}
/>
</Switch>
</CSSTransition>
</TransitionGroup>
</div>
)}
/>
Transition works fine for this code. But I want to remove transition animation of /profile Route.
Is there any way to remove it?
Is there any way to maintain profile route inside switch and solve this issue?
hacky, but works: <CSSTransition key={location.key} timeout={somecond ? 500 : 0} classNames={somecond ? 'working-class' : ''}>.... better idea?
@ondrejrohon I could not find any perfect condition there. I added location.pathname !== '/profile' as condition. But will fail when we navigate to profile. Navigation from profile works well.
I think this requires some rendering acrobatics because we can enable/disable exiting transition only _before_ we know what the next route will be. One solution is this:
<Route
render={({ location }) => {
const routes = (
<Switch location={location}>
<Route
path="/login"
exact
render={routeProps => (<LoginPage {...routeProps} />)}
/>
<Route
path="/logout"
exact
render={(routeProps: any) => (<LogoutPage {...routeProps} />)}
/>
<PrivateRoute
path="/"
exact
render={(routeProps: any) => <HomePage />}
/>
<PrivateRoute
path="/profile"
exact
render={(routeProps: any) => (<Profile {...routeProps} />)}
/>
</Switch>
)
return (
<div className="App">
{[
{ name: 'Login', pathname: '/login' },
{ name: 'Logout', pathname: '/logout' },
{ name: 'Home', pathname: '/' },
{ name: 'Profile', pathname: '/profile' },
].map(({ name, pathname }) => (
<Link
key={pathname}
to={{ pathname, state: { fromPathname: location.pathname } }}
>
{name}
</Link>
))}
{location.pathname === '/profile' ? routes : (
<TransitionGroup
enter={location.state.fromPathname !== '/profile'}
className="transition-item"
>
<CSSTransition
key={location.key}
timeout={300}
classNames="fade"
>
{routes}
</CSSTransition>
</TransitionGroup>
)}
</div>
)
}}
/>
It consists of three parts:
Link components./profile. This will prevent exiting animation of any previous route and entering animation of the current (profile) route.enter animation on TransitionGroup if the previous route was /profile. When navigating away from /profile, this will prevent the entering animation of the new route.I'm not sure what are your exact animation requirements, so you can tweak these as you wish. Let me know if you have questions!
I honestly having played around with React router in a while but it seems like to do transitions, Route should be the thing with the Transition in it and there should be no TransitionGroup...
How would you make an exit transition in that case?
when children is a function for Route, it gets called regardless of whether the route is matched or not: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Route.js#L122
Could do something like
<Route>
{({ match }) => <Transition in={!!match} />
</Route>
Oh wow, that was my missing piece of the puzzle!
Most helpful comment
when
childrenis a function forRoute, it gets called regardless of whether the route is matched or not: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Route.js#L122Could do something like