React Transitionable Route

With both Reach Router and react-transition-group this simple blog had a bit too much JavaScript, so decided to build my own react router, with transitionable routes.

Admittedly, there's a lot more I could have done to minimise the weight of this blog, and improve render time – such as not using a framework, using a smaller framework (preact) and so on. For the time being, I thought I'd write a router with hooks, enable SSR, and add some sort of transitioning logic to it.

For lack of better name I've named it @stilva/transitionable-react-router.

My website runs with this router, so check out how I've put it together here @stilva/stilva.com.

I've built it with hooks and somewhat followed react-transition-group's latest API. I really like their v1 API which allowed the components to dictate when a transition is done, as opposed to hard-coding a timeout for all transitions. For routes, however, I wasn't convinced this feature was needed, so I opted for the components to receive a transition state prop.

I believe all the unit tests can serve as a great documentation, so I'd check these out TransitionableReactRoute.test.js.

For now, here's a brief overview of how to use TransitionableReactRoute:

<TransitionableReactRoute timeout={850} animateOnMount={true} > <LabList path="/lab" /> <LabEntry path="/lab/:labId" /> <Home defaultpath /> </TransitionableReactRoute>

Each path is transformed into a regular expression that is then matched against the URL. Consequently, path matching is eager, so the order in which your components are declared matters.

Like with all your React components, you can nest your TransitionableReactRoute components.

<TransitionableReactRoute timeout={850} animateOnMount={true} > <TransitionableReactRoute path="/nested" > <One path="one" /> {{// will match /nested/one }} </TransitionableReactRoute> </TransitionableReactRoute>

One of the few missing pieces with React-Transitionable-Router – apart from a better name – is a sort of Link component. For the time being, I'm just using the context as below:

import {useContext} from "react"; import {RouterContext} from "@stilva/transitionable-react-router"; export function Link({label, path}) { const {setRouter} = useContext(RouterContext); return <a href="path" onClick={e => setRouter(path)}> {label} </a>; }