Home > Blockchain >  React Router v6: Route tracking with matchRoutes
React Router v6: Route tracking with matchRoutes

Time:08-30

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>
  • Related