I'm struggling to make React-Router work well with CSSTransition, which seems to be the defacto library for this around the web.
I'm using React-Router v6 without any issue. I'm not sure if the issue is due to that or not being that it is more recent.
My goal is to animate between my different route with an animation that plays when clicked-in and another that plays when clicked-out.
In term of style, I'm just looking at a simple "Slide-in" animation. Where my first component will slide-in-from-bottom and slide-out-to-bottom before the second component will slide-in-from-right and eventually slide-out-to-right when clicked out. and things like that.
I can't believe this is so hard to put into practice. I am definitely not the first one that wants to do this.
I'm open to any suggestion that'll work and that uses React-Router.
I would gladly take any help and any method that works at this point.
thanks.
My bare code just for reference (I have discarded everything I've tried and started fresh):
const App = () => {
const location = useLocation();
return (
<div className="app">
<section className="main">
<Routes>
<Route index element={<Home />} />
<Route path="home" element={<Home />} />
<Route path="marketplace" element={<Marketplace />} >
<Route index element={<Listing />} />
<Route path="listing" element={<Listing />} />
<Route path="cart" element={<Cart />} />
</Route>
</Routes>
</section>
<nav className="main-nav">
<ul>
<li>
<NavLink to="/home" className={(navdata) => (navdata.isActive ? 'active' : 'none')} >
<span className="nav-text">Home</span>
</NavLink>
</li>
<li>
<NavLink to="/marketplace" className={(navdata) => (navdata.isActive ? 'active' : 'none')} >
<span className="nav-text">Store</span>
</NavLink>
</li>
<li>
<NavLink to="/aboutus" className={(navdata) => (navdata.isActive ? 'active' : 'none')} >
<span className="nav-text">About Us</span>
</NavLink>
</li>
<li>
<NavLink to="/user" className={(navdata) => (navdata.isActive ? 'active' : 'none')} >
<span className="nav-text">My Account</span>
</NavLink>
</li>
</ul>
</nav>
</div>
);
};
The key part of a solution to creating transitions between routes is dealing with exit transitions, and making sure the old route doesn't disappear instantly so we have time to see the exit. By passing a function as the child of Route, we are able to achieve that.
To achieve a unique transition on each Route we simply need to provide each Route with it's own CSSTransition and set up the css properties for each transition.
A single Route would look like this:
<Route path="/user">
{({ match }) => (
<CSSTransition
in={match != null}
classNames="spin"
timeout={500}
unmountOnExit
>
<div className="absolute">
<Marketplace />
</div>
</CSSTransition>
)}
</Route>
And here is a full example set up in codesandbox with four example of routes with unique transitions. They are not very pleasing animations, but are designed to show the concept clearly.
This page has some great info about how to do this and what potential issues to watch out for, such as the need to use absolute or fixed positioning:
Exit transitions will cause the content of routes to linger until they disappear, which might pose some styling challenges. Make sure that routes don't affect each other's layout, for example you can remove them from the flow of the document by using absolute or fixed positioning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With