We used our own in-house Route-component to track routes in react-router-dom
v5. It looked roughly like this:
import { Switch, Route } from 'react-router-dom';
const routes = () => (
<Switch>
<TrackedRoute title="title to track" path="/path/home" component={Home} />
<TrackedRoute title="title to track" path="/path/contact" component={Contact} />
</Switch>
)
const TrackedRoute = ({ title, ...others }) => {
doTrackingThings(title);
return (
<Route {...others} />
);
}
But in React Router v6 the Routes component only accepts its own <Route>
objects. This is enforced through type equality. Additionally optional params are no longer allowed in route paths, which made our tracking more complicated. If we want to track which route the user is on, how do we do this in React Router v6?
CodePudding user response:
We ended up moving the tracking up to the new <Routes>
component (which replaces Switch). It looks roughly like this:
import { Routes, Route, matchRoutes, useLocation, useRoutes } from 'react-router-dom';
const routes = () => (
<TrackedRoutes>
<Route path="/path/home" component={Home} />
<Route path="/path/contact" component={Contact} />
</TrackedRoutes>
);
const TrackedRoutes = ({ children, location }) => {
// Add our tracking, find all routes that match and track it
const currentLocation = useLocation();
const someRoutes = [
{ path: "/path/home" },
{ path: "/path/contact" },
];
const matches = matchRoutes(someRoutes, currentLocation);
doTrackingThings(matches);
// Pretend to be the real <Routes> component
return useRoutes(createRoutesFromChildren(children), location);
}
The real implementation of <Routes>
is actually very short, as seen here.
CodePudding user response:
I would make a component e.g. Tracked and wrap in it element itself:
const Tracked = ({title, children})=>{
doTrackingThings(title);
return children
}
//then
<Routes>
<Route path="/home" element={<Tracked title='home'><Home/></Tracked>}/>
</Routes>