Reputation: 1119
I'm using react-router v6, Is it possible to use nested routes without using the Outlet component?
For example: I have a users page and onClick on a user component it should navigate to the specific user page,
Current try:
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<Users />} />
<Route path=":id" element={<UserPage/>} />
</Routes>
And on click on a specific user:
const gotoUserPage = () => {
navigate('1')
}
The gotoUserPage change the URL from '/users' to '/users/1' but the userPage component doesn't render.
Upvotes: 12
Views: 15298
Reputation: 51
I am using nested <Routes></Routes>
component in react-router-dom v6 and it is working. But in console sometimes there is warning message "No routes matched location ...someLocation..."
and i guess if this method is correct. But it is not convenient for me to use <Outlet/>
.
In the example below PageRouting
contains Page
. Page
contains NestedPageRouting
. And NestedPageRouting
contains NestedPage
. Slash and asterisk (/*
) in the end of path segment allow nested routing. First slash in the path in comments assumes that <PageRouting/>
is the root routing.
function PageRouting(){
return <Routes>
{/* path: /page */}
<Route path="page/*" element={<Page/>}/>
<Route path='*' element={<div>No routes matched</div>}/>
</Routes>
}
function Page(){
return <div>
<div>Some content</div>
<NestedPageRouting/>
</div>
}
function NestedPageRouting(){
return <Routes>
{/* path: /page/nestedPage */}
<Route path="nestedPage/*" element={<NestedPage/>}/>
<Route path='*' element={<div>No routes matched</div>}/>
</Routes>
}
function NestedPage(){
return <div>Some Nested Content</div>
}
Upvotes: 1
Reputation: 31
It is possible to use routes without using the <Outlet />
component, what you simply need to do is shown below. Use the same path of the parent component and add the :id
:
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<Users />} />
<Route path="users/:id" element={<UserPage/>} />
</Routes>
However if you are concerned about the fact that the <Outlet />
component renders on the same page with the Parent component when nested, then you can hide the Parent component when the child component is active like this:
1. Use Flat Routes
Add the <UserPage />
component in the routes like this:
<Routes>
<Route path="/" element={<Home />} />
<Route path="users" element={<Users />} >
<Route path=":id" element={<UserPage />} />
</Route>
</Routes>
2. Parent Component Conditional Render
Add a condition to NOT render contents of Parent component if there exist a params.id
property, this uses Outlet but helps you avoid showing some elements.
let params = useParams();
<div>
!params.id && (<div>
*render your contents here* </div>)
<Outlet />
</div>
So whenever the child component is loaded, the Parent component is not visible.
Upvotes: 3
Reputation: 81
Yes you can do that with some trick. Here is my trick
<OutletPage />
)Like this
<Route path="profile" element={<ProfilePageOutlet />}>
<Route index element={<ProfilePage />} />
<Route path="my-profile" element={<MyProfilePage />} />
</Route>
<ProfilePageOutlet />
looks like this
import { Outlet } from "react-router-dom";
function ProfilePageOutlet() {
return <Outlet />;
}
export default ProfilePageOutlet;
<MyProfilePage />
is a simple page
Upvotes: 0
Reputation: 203408
Is it possible to use nested routes without using the Outlet component?
No, an Outlet
component is required in order to render the nested Route
components.
Either the Users
component must render an Outlet
component, or you can render directly an Outlet
as a layout component.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<Outlet />}>
<Route index element={<Users />} /> // "/users"
<Route path=":id" element={<UserPage/>} /> // "/users/:id"
</Route>
</Routes>
Though, a better or more accurate question may be, do you even need to explicitly render an Outlet
as a layout element? The answer may surpisingly be "no". Route
components render an Outlet
by default on the element
prop.
The default
<Route element>
is an<Outlet>
. This means the route will still render its children even without an explicit element prop, so you can nest route paths without nesting UI around the child route elements.
You can simply wrap some nested routes in a Route
and specify only the path
for nesting, and the nested routes will be rendered into an Outlet
by default.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users">
<Route index element={<Users />} /> // "/users"
<Route path=":id" element={<UserPage/>} /> // "/users/:id"
</Route>
</Routes>
Upvotes: 22
Reputation: 2428
This is an optimised way of doing what @hellocng has explained:
<Routes>
<Route path="/" element={<Home />} />
<Route path="users" element={<Outlet />}>
<Route index element={<Users />} />
<Route path=":id" element={<UserPage />} />
</Route>
</Routes>
Upvotes: 4
Reputation: 124
What's wrong with using the <Outlet/>
component? It tells React Router where to render the <UserPage/>
so without it, there is no place for the page to render, as expected.
If you are wondering how to render the page without it being a child of the <Users/>
page, then you can try the following:
<Routes>
<Route path="/" element={<Home />} />
<Route path="users" element={<Outlet />} />
<Route path="/" element={<Users />} />
<Route path=":id" element={<UserPage />} />
</Routes>
There are definitely times when a whole different component is necessary, but in most cases, components share certain components, such as nav bar and containers. If you have a nav bar in both the Users and UserPage components, then you may want to consider refactoring it out of both, and put it in a parent component with the nav bar and Outlet. This will help with managing conponents as you scale.
Upvotes: 6