Reputation: 5106
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';
// EDIT: This was React-Router v5 code, in v6 <Switch> is replaced by <Routes>
// and <Route component={}> is replaced by <Route element={}>
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?
Upvotes: 2
Views: 6101
Reputation: 5106
We ended up moving the tracking to a separate component. It looks roughly like this:
import { BrowserRouter, Routes, Route, matchRoutes, useLocation } from 'react-router-dom';
const app = () => (
<BrowserRouter>
<Routes>
<Route path="/path/home" element={<Home />} />
<Route path="/path/contact" element={<Contact />} />
</Routes>
<RouteTracker />
</BrowserRouter>
);
const RouteTracker = () => {
// 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);
return null;
}
We wanted to do tracking in one single location (the app is large). For someone else having a <Tracked>
component like the other answers suggest may be a better fit.
Upvotes: 2
Reputation: 24980
Switch
is changed as Routes
in v6. As we have nested elements , we can return the props
of children to parent.
const Tracked = ({title, children})=>{
// use title here
return children // as props for the parent
}
Call it as:
<Routes>
<Route path="/home" element={<Tracked title='title'><Home/></Tracked>}/>
</Routes>
Upvotes: 0
Reputation: 1154
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>
Upvotes: 1