Lab 21 a: Route Transitions
This lab is optional and should only be done if time permits
Objectives
- Animate in and out pages as routes transition
Steps
Install the
react-transition-group
library.React Transition Group
exposes simple components useful for defining entering and exiting transitions.React Transition Group used to be part of the
React
library itself but has since been removed and is part ofReactCommunity.org
.# npm
npm install react-transition-group
# if using TypeScript
npm install @types/react-transition-group
# yarn
yarn add react-transition-groupMove the
<Router>
component up one level to wrap the entireApp
. This is necessary for us to be able to access the newuseLocation
hook that is part ofreact-router
at the point we use theCSSTransition
andRoutes
components. We get thelocation
using theuseLocation
hook.You can't use any of the hooks from within the same component that puts the Router into the tree. You need to move your BrowserRouter out of that component. It can go in the root.render() call, for instance.
React Transition Group
is not an animation library likeReact-Motion
, it does not animate styles by itself. Instead it exposes transition stages, manages classes and group elements and manipulates the DOM in useful ways, making the implementation of actual visual transitions much easier.src\App.js
...
import {
- BrowserRouter as Router,
Route,
NavLink,
Routes,
+ useLocation,
} from 'react-router-dom';
...
function App() {
+ let location = useLocation();
return (
<Provider store={store}>
- <Router>
<header className="sticky">
<span className="logo">
<img src="/assets/logo-3.svg" alt="logo" width="49" height="99" />
</span>
<NavLink to="/" className="button rounded">
<span className="icon-home"></span>
Home
</NavLink>
<NavLink to="/projects/" className="button rounded">
Projects
</NavLink>
</header>
<div className="container">
<Routes location={location}>
<Route path="/" component={HomePage} />
<Route path="/projects" component={ProjectsPage} />
<Route path="/projects/:id" component={ProjectPage} />
</Routes>
</div>
- </Router>
</Provider>
);
}
export default App;src\index.js
...
+ import { BrowserRouter as Router } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
+ <Router>
<App />
+ </Router>
</React.StrictMode>
);Wrap the
react-router
'sRoutes
component with aTransitionGroup
andCSSTransition
component from thereact-transition-group
library.src\App.js
+ import { CSSTransition, TransitionGroup } from 'react-transition-group';
function App() {
let location = useLocation();
return (
<Provider store={store}>
<header className="sticky">
<span className="logo">
<img src="/assets/logo-3.svg" alt="logo" width="49" height="99" />
</span>
<NavLink to="/" className="button rounded">
<span className="icon-home"></span>
Home
</NavLink>
<NavLink to="/projects/" className="button rounded">
Projects
</NavLink>
</header>
<div className="container">
+ <TransitionGroup>
+ <CSSTransition key={location.key} classNames="fade" timeout={{ enter: 400, exit: 200 }}>
- <Routes>
+ <Routes location={location}>
<Route path="/" component={HomePage} />
<Route path="/projects" component={ProjectsPage} />
<Route path="/projects/:id" component={ProjectPage} />
</Routes>
+ </CSSTransition>
+ </TransitionGroup>
</div>
</Provider>
);
}
export default App;
Add the
page
andfade
CSS styles.src\index.css
...
/* add these below existing styles */
.fade-enter {
opacity: 0;
z-index: 1;
}
.fade-enter.fade-enter-active {
opacity: 1;
transition: opacity 400ms ease-in;
}
.fade-exit.fade-exit-active {
opacity: 1;
transition: opacity 200ms ease-in;
}This style should already exist but it is also important to ensure your container has a height of 100 percent.
.container {
height: 100%;
}Click through the pages in the application and see the previous page content fade out and the new page content fade in to view.
Libraries Compared
React Transition Group just makes transitions easier. It is not an animation library. React Spring and React Framer Motion are animation libraries. Historically, React Spring has been the most popular library but React Framer Motion was released more recently and tends to be easier to use and comprehend. This article can be useful in making a decision on a library: What’s the most developer-friendly React animation library?.