This is a variant of <Switch>
that's much easier to use with transition components and solves some problems.
The current recommended transition approach for react-router
is
import { Route, Switch } from 'react-router-dom'
import Fader from 'react-fader'
const MyRoute = () => (
<Route
render={({ location }) => (
<Fader>
<Switch key={location.key} location={location}>
<Route path="/red" component={Red} />
<Route path="/green" component={Green} />
<Route path="/blue" component={Blue} />
</Switch>
</Fader>
)}
/>
)
This has several problems:
- All
<Switch>
es transition on everylocation
change, even if:- only the last part of the URL changed and you only want the innermost nested
<Switch>
to transition - you have the same component for two different paths and don't want to transition that component
- you don't want to transition in some case for any other reason
- only the last part of the URL changed and you only want the innermost nested
- You have to pass a
location
to the<Switch>
for it to work
react-router-transition-switch
simplifies the above example to
import { Route } from 'react-router-dom'
import Switch from 'react-router-transition-switch'
import Fader from 'react-fader'
const MyRoute = () => (
<Switch component={Fader}>
<Route path="/red" component={Red} />
<Route path="/green" component={Green} />
<Route path="/blue" component={Blue} />
</Switch>
)
- You can pass it a
component
orrender
prop. It will use them to wrap the matched<Route>
if given - By default it clones the matched
<Route>
withkey={match.url}
unless you gave the<Route>
a key yourself. This way theFader
will only perform a transition when:- if you provide
key
s yourself, the matched<Route>
has a differentkey
than the last - otherwise, the matched portion of the
location
is different from the last`
- if you provide
- You can pass it a
createKey
prop, which is a function taking the(route, match)
and returning the key to use.
import React from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Fader from 'react-fader'
import Switch from 'react-router-transition-switch'
// ...
const MyRoute = () => (
<Router>
<Switch component={Fader}>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/account" component={Account} />
<Route path="/users/:userId" component={User} />
</Switch>
</Router>
)
For the location /users/andy/profile
, the <Switch>
will render:
<Fader>
<Route key="/users/andy/profile" path="/users/:userId" component={User} />
</Fader>
Notice that it makes match.url
the key
of the matched <Route>
, so that <Fader>
(or whatever transition component
you use) knows to perform a transition. If you provide custom key
s on the <Route>
s you pass to <Switch>
, it won't
overwrite them.
As with <Route>
, you may pass a render
function instead of a component
:
<Router>
<Switch
render={({ children }) => (
<ReactCSSTransitionGroup
transitionName="example"
transitionEnterTimeout={300}
transitionLeaveTimeout={300}
>
{children}
</ReactCSSTransitionGroup>
)}
>
...
</Switch>
</Router>
If you want to prevent transitions between certain <Route>
s, give them the same key
. This will not cause problems
because <Switch>
only renders one of the child <Route>
s it was passed, so there will never be duplicate keys during
React's reconciliation step.
<Router>
<Switch component={Fader}>
<Route key="home" exact path="/" component={Home} />
<Route key="orders" exact path="/orders" component={Orders} />
<Route key="orders" path="/orders/:orderId" component={Orders} />
<Route key="about" path="/about" component={About} />
</Switch>
</Router>
If you have to pass in an array of <Route>
s, they will already have
keys, hence changes between subroutes will not transition since
react-router-transition-switch
does not override existing keys with the
match.url
.
In this case, you can use the createKey
prop to force a unique key for
every match
:
<Router>
<Switch component={Fader} createKey={(child, match) => match.url}>
{routes}
</Switch>
</Router>