Nested routes with react router v4 / v5
In react-router-v4 you don't nest <Routes />
. Instead, you put them inside another <Component />
.
For instance
<Route path='/topics' component={Topics}>
<Route path='/topics/:topicId' component={Topic} />
</Route>
should become
<Route path='/topics' component={Topics} />
with
const Topics = ({ match }) => (
<div>
<h2>Topics</h2>
<Link to={`${match.url}/exampleTopicId`}>
Example topic
</Link>
<Route path={`${match.path}/:topicId`} component={Topic}/>
</div>
)
Here is a basic example straight from the react-router documentation.
I need a nested route in react router V5
Within the Switch
component path order and specificity matters! You want to order the routes from more specific paths to less
specific paths. In this case you are rendering the "/access"
path prior to any of the sub-route "/access/***"
paths, so it is matched and rendered instead of the one really matching the path in the URL.
To fix, move the "/access"
route config below the more specific routes.
export const ROUTES = [
// move "/access" route from here
{
name: "addTeam",
path: "/access/add-team",
component: lazy(() => import("./AddTeam"))
},
{
name: "addUser",
path: "/access/add-user",
component: lazy(() => import("./AddUser"))
},
// to here
{
name: "access",
path: "/access",
component: lazy(() => import("./Access"))
},
{
name: "admin",
path: "/admin",
component: lazy(() => import("./Admin"))
}
];
react-router v5 – nested routes
Apart from typo that you pointed out for declaring to
instead of path
You can wrap Dashboard
component Route
s in a Switch
const Dashboard = (props) => (
<div className={styles.views}>
<Switch>
<Route
path="/dashboard/reports/create"
render={() => <ReportsForm {...props} />}
exact
/>
<Route
path="/dashboard/reports"
render={() => <Reports {...props} />}
exact
/>
</Switch>
</div>
);
If that dont work you can even wrap the entire thing in Route with initial path as follows:
const Dashboard = props => (
<div className={styles.views}>
<Route path="/dashboard/reports"> // <------------------
<Switch>
<Route path="/dashboard/reports/create" render={() => <ReportsForm {...props} />} exact />
<Route path="/dashboard/reports" render={() => <Reports {...props} />} exact />
</Switch>
</Route>
</div>
);
Here's the working example solution that I just created: https://stackblitz.com/edit/react-uih91e-router-nested?file=index.js
is it ok to use React Router Nested routes
These are descendent routes, not nested routes, but that doesn't matter as the question, as posed, is a bit subjective. react-router-dom
allows it, so yes, it's ok to do. There is no issue with React components rendering descendent routes.
This is a very common routing pattern in RRDv4/5. RRDv6 allows it and made nesting routes even easier than in previous versions.
I'm not sure where exactly you were looking for examples of rendering descendent/"nested" routes and not finding any, but there's an official Nesting Example in the v5 docs.
React Router v5 - element under nested route not displaying
You appear to be mixing RRDv5 and RRDv6 component API/syntax. If using RRDv5 the descendent route rendered by HeatMapContainer
should render content on the component
prop (or render
or children
function props) instead of a non-existent element
prop.
<Switch>
<Route path="/table" component={TablePage} />
<Route path="/heatmap" component={HeatMapContainer} />
<Route path="/" exact component={LandingPage} />
<Route component={NotFoundPage} />
</Switch>
HeatMapContainer
<div style={{ display: 'flex', justifyContent: 'center', width: '100%' }}>
HEAT MAP CONTAINER
<Link to="/heatmap/all">All</Link>
<Route path="/heatmap/all" component={AllOfficesRoute} />
</div>
React Router v5.0 Nested Routes
It took me some time to find the answer that I favoured.
Both @johnny-peter & @gaurab-kc solutions were great and they tought me about React's routing mechanism.
@johnny-peter 's solution had disadvantage of forcing me to put a prefix for all auth
related routes under /auth/...
(e.g. /auth/login
& auth/sign-up
) which I didn't wanted.
@gaurab-kc solution was supporting only one set of routes.. so if user was already signed up, he couldn't visit the /login
route anymore.
Up till recently I used my own solution which had the problem of "defeating the whole purpose of a common header and footer." as @johnny-peter mentioned and it was down-voted few times as it should be.
Now I'm using another solution:
<Router history={browserHistory}>
<Switch>
<Redirect exact from="/" to="/home"/>
<Route exact path={["/login", "/sign-up", ...]}>
<AuthLayout>
<Switch>
<Route
path="/login"
component={LoginPage}
/>
<Route
path="/sign-up"
component={SignUpPage}
/>
</Switch>
</AuthLayout>
</Route>
<Route exact path={[
"/home",
"/dashboard",
...
]}>
<SiteLayout>
<Switch>
<Route
path="/home"
component={HomePage}
/>
<Route
path="/dashboard"
component={DashboardPage}
/>
</Switch>
</SiteLayout>
</Route>
<Route path="*" component={NotFoundPage}/>
</Switch>
</Router>
which prevents all the above disadventages. It's allows me to:
- Use a layout for each section which isn't re-rendered on route change.
- Doesn't forcing me to add any prefix to routes.
- All routes are working at the same time, letting users to route back into the
/login
or otherauth
routes without logout first.
The only disadvantage of this solution is having more code and duplicating the routes, but it's a cost I'm willing to pay.
Nested routing using protected routes is not working properly
I don't really know what ProtectRouteProps is and what I should put in it.
There are no props. This is clear by the usage:
<Route path='/createItem' element={<ProtectRoute />} />
No props are passed to ProtectRoute
. You can drop the props object:
import { Navigate, Outlet } from "react-router";
import { RootStateOrAny, useSelector } from "react-redux";
export default function ProtectRoute() {
const userSignin = useSelector((state: RootStateOrAny) => state.userSignin);
const { userInfo } = userSignin;
return userInfo?.user?.isAdmin ? <Outlet /> : <Navigate to='/' replace />;
}
The problem now is that can't access CreateItem because is going on
the ProtectRoute page that is an empty one. What should i do?
"Auth" routes are what are called layout routes. They apply some logic, perhaps some styled layout CSS, and render an Outlet
for nested Route
components to be rendered into. The nested Route
components use the path
prop for route matching.
Example:
<Route element={<ProtectRoute />}>
<Route path='/createItem' element={<CreateItem />} />
... other protected routes ...
</Route>
Related Topics
How to Cancel an Http Fetch() Request
What Is the Meaning of "$" Sign in JavaScript
Why Is My Function Call That Should Be Scheduled by Settimeout Executed Immediately
How Is Almost Everything in JavaScript an Object
JavaScript - Href VS Onclick for Callback Function on Hyperlink
Getting All Variables in Scope
Differencebetween 'New Object()' and Object Literal Notation
Recurring Events in Fullcalendar
Jquery .Ready in a Dynamically Inserted Iframe
Facebook Social Plug-In Not Showing Up When Added Dynamically
How to Prevent Enter Keypress to Submit a Web Form
How to Get a JavaScript Object's Class
Call ASP.NET Function from JavaScript
How to Display Length of Filtered Ng-Repeat Data
Es6 Modules: Export Single Class of Static Methods or Multiple Individual Methods
Http Headers in Websockets Client API