I'm attempting to create a few routes on my web app using react-router. However, some pages need to share components - such as the Navigation or Footer - where others do not.
What I essentially need is a way to check if a path doesn't match a few preset locations, and if it doesn't then render the content.
At the moment I'm doing this like so:
const displayComponentIfAllowed = (location, component) => {
const C = component;
const globalComponentsDisallowedPaths = ["/booking"];
// If the path matches something within the blocked list, then return null.
let allowToRender = true;
globalComponentsDisallowedPaths.forEach(disallowedPath => {
if(location.pathname === disallowedPath){
allowToRender = false;
}
});
// Otherwise, return component to render.
return allowToRender ? <C /> : null;
}
return (
<Router>
<Routes>
<Route render={({ location }) => displayComponentIfAllowed(location, Navigation)} />
<Route path="/">
<Route index element={<Home />} />
<Route path="booking/:customer_id" element={<Booking />} />
</Route>
<Route render={({ location }) => displayComponentIfAllowed(location, Footer)} />
</Routes>
</Router>
);
However, ever since V6 of react-router-dom has been introduced, this doesn't seem to work. I imagine this is because the render prop has been deprecated (although I'm unsure, but there's no mention of it in the docs).
Are there any workarounds - or a better implementation of this which works with V6? Cheers
Create a layout component that renders the UI components you want and an Outlet for nested routes to be rendered into.
Example:
import { Outlet } from 'react-router-dom';
const HeaderFooterLayout = () => (
<>
<Navigation />
<Outlet />
<Footer />
</>
);
...
import {
BrowserRouter as Router,
Routes,
Route
} from "react-router-dom";
...
<Router>
<Routes>
<Route element={<HeaderFooterLayout />} >
<Route path="/">
<Route index element={<Home />} />
... other routes you want to render with header/footer ...
</Route>
</Route>
<Route path="booking/:customer_id" element={<Booking />} />
... other routes you want to not render with header/footer ...
</Routes>
</Router>