I found that I am having to reorganize my routes switching from React-Router-Dom v5 to v6.
I have this outer route:
<Route
path="/abc/product/:skuType/:skuPage?"
element={
<PrivateRoute>
<ProductRoutesStructure />
</PrivateRoute>
}
/>
But none of my routes are matching. So I am unsure how to match. For instance, in one route, it looks like this: 'abc/product/1234/converse'
and I am doing this:
export const ProductRoutesStructure = () => (
<Routes key="productRoutes">
<Route
path={`/abc/product/:skuType/:skuPage(${Types.CONVERSE})`}
element={<SneakerPage />}
/>
<Route
path={`/abc/product/:skuType/:skuPage(${Types.PANTS})`}
element={<PantsPage />}
/>
<Route path="*" element={<GenericPage />} />
</Routes>
)
The things is that skuType
and skuPage
must be dyanmic as in those element
components since I hit certain APIs. I just am really needing to match on the skuPage
.
I think I am missing some nuance of sub pages. I tried matching on just "Types.CONVERSE", but that is a no go, it always defaults to the last bit "*"
catch-all route.
This is what I am expecting and this most certainly worked in v5, as this is actual code I used (pathing is different/names). But exactly the same. Worked like a charm, but v6, nope.
So, if a user goes to "www.myDomain/abc/product/male/converse"
I expect that to match this route:
<Route
path={`/abc/product/:skuType/:skuPage(${Types.CONVERSE})`}
element={<SneakerPage />}
/>
If a user goes to "www.myDomain/abc/product/female/pants"
It would match:
<Route
path={`/abc/product/:skuType/:skuPage(${Types.PANTS})`}
element={<PantsPage />}
/>
But lets just make it work. I have no problem altering my routes in ProductRoutesStructure
, but I tried a bunch of combinations, and nothing is matching.
Mind you, I do need skuType
and skuPage
to be available to child components/pages, that is why I need it in the base route.
From what I understand you have basically this "/abc/product/:skuType/:skuPage"
route path that you'd like to match and render dynamic content on.
Render a single "/abc/product/:skuType/:skuPage"
route and use a regular old Javascript switch
statement to conditionally render the correct routed content based on the skuPage
route path parameter.
Outer Route
<Routes>
<Route
path="/abc/product/:skuType/:skuPage"
element={
<PrivateRoute>
<ProductRoutesStructure />
</PrivateRoute>
}
/>
</Routes>
ProductsRoutesStructure
import { useParams } from 'react-router-dom';
const ProductRoutesStructure = () => {
const { skuPage } = useParams();
switch (skuPage) {
case Types.CONVERSE:
return <SneakerPage />;
case Types.PANTS:
return <PantsPage />;
default:
return <GenericPage />;
}
};
The routed content components use the useParams
hook to access their route parameters.
const SneakerPage = () => {
const { skuPage, skuType } = useParams();
return (
<>
<h1>SneakerPage</h1>
<div>{skuType} - {skuPage}</div>
</>
);
};
const PantsPage = () => {
const { skuPage, skuType } = useParams();
return (
<>
<h1>PantsPage</h1>
<div>{skuType} - {skuPage}</div>
</>
);
};
Render each specific skuPage
directly, passing the skuPage
value down as props to the routed content components.
Outer Route
<Routes>
<Route
path="/abc/product/:skuType/*" // <-- wildcard matcher for descendent routes
element={
<PrivateRoute>
<ProductRoutesStructure />
</PrivateRoute>
}
/>
</Routes>
ProductRoutesStructure
const ProductRoutesStructure = () => (
<Routes key="productRoutes">
<Route
path={Types.CONVERSE}
element={<SneakerPage skuPage={Types.CONVERSE} />}
/>
<Route path={Types.PANTS} element={<PantsPage skuPage={Types.PANTS} />} />
<Route path="*" element={<GenericPage />} />
</Routes>
);
const SneakerPage = ({ skuPage }) => {
const { skuType } = useParams();
return (
<>
<h1>SneakerPage</h1>
<div>
{skuType} - {skuPage}
</div>
</>
);
};
const PantsPage = ({ skuPage }) => {
const { skuType } = useParams();
return (
<>
<h1>PantsPage</h1>
<div>
{skuType} - {skuPage}
</div>
</>
);
};