React Router 6: Advanced Routing with useOutlet and useOutletContext
React Router is a popular routing library for React applications that provides a declarative way to navigate between different pages. One of the lesser-known features of React Router is the useOutlet
and useOutletContext
hooks. In this article, we will explore how to use these hooks to create more advanced routing features in a React application.
What is useOutlet and useOutletContext?
The useOutlet
hook is a function provided by React Router that can be used to render the child routes of a parent route. This is useful when you want to create nested routes that share a common layout or wrapper component. For example, if you have a dashboard page with multiple tabs, you can use the useOutlet
hook to render the content of each tab within the dashboard page.
The useOutletContext
hook is a function that returns the context object of the parent route. This can be useful when you want to access properties of the parent route, such as the route path or any route parameters.
How to use useOutlet and useOutletContext
Let’s start with an example. Suppose we have a Dashboard
component that renders a list of items and a Details
component that displays the details of a selected item. We want to create a route that allows the user to click on an item in the list and display the details of that item in the Details
component.
First, we need to define our routes using the Route
and Routes
components from React Router. Here is an example of how we can define our routes:
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="details/:id" element={<Details />} />
</Routes>
</Router>
);
}
In this example, we have two routes. The first route is the root route, which displays the Dashboard
component. The second route is a child route of the root route, and it displays the Details
component. Note that we have defined a route parameter called id
in the path of the Details
route.
Now let’s create our Dashboard
component. We want to display a list of items, and when the user clicks on an item, we want to display the details of that item. Here is an example of how we can define our Dashboard
component:
function Dashboard() {
const items = [
{ id: 1, name: "Item 1" },
{ id: 2, name: "Item 2" },
{ id: 3, name: "Item 3" },
];
return (
<div>
<h1>Dashboard</h1>
<ul>
{items.map((item) => (
<li key={item.id}>
<Link to={`/details/${item.id}`}>{item.name}</Link>
</li>
))}
</ul>
<Outlet />
</div>
);
}
In this example, we have defined a list of items, and we have rendered each item as a link using the Link
component from React Router. Note that we have used a template literal to generate the path of the link dynamically based on the id
of the item.
We have also included the Outlet
component from React Router. This component is where the child routes of the Dashboard
route will be rendered.
Now let’s create our Details
component. We want to display the details of the selected item based on the id
parameter in the route path. Here is an example of how we can define our Details
component:
function Details(props) {
const { id } = useParams();
const item = getItemById(id);
return (
<div>
<h1>{item.name}</h1>
<p>{item.description}</p>
<Outlet />
</div>
);
In this example, we have used the `useParams` hook from React Router to extract the `id` parameter from the route path. We have then used a custom function called `getItemById` to retrieve the item with the corresponding `id`. Note that we have included the `Outlet` component again. This is because the `Details` route may have additional child routes that we want to render within the `Details` component.
Finally, let’s talk about how to use the `useOutletContext` hook. Suppose we want to display the route path of the parent route above the `Details` component. Here is an example of how we can do that:
function Details(props) {
const { id } = useParams();
const item = getItemById(id);
const { outlet } = useOutletContext();
return (
<div>
<h2>{outlet.route.path}</h2>
<h1>{item.name}</h1>
<p>{item.description}</p>
<Outlet />
</div>
);
}
In this example, we have used the useOutletContext
hook to access the context object of the parent route. We have then used the outlet.route.path
property to display the path of the parent route above the Details
component.
Conclusion
In this article, we have explored how to use the useOutlet
and useOutletContext
hooks from React Router. These hooks allow us to create more advanced routing features in a React application, such as nested routes and route parameter extraction. By using these hooks, we can create more dynamic and flexible user interfaces that enhance the user experience.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
My Setup:
💻 Apple 2023 MacBook Pro M2 — https://amzn.to/3N4uuQA
⌨️ Apple Magic Keyboard — https://amzn.to/40yo8vM
🖱 Apple Magic Mouse — https://amzn.to/40szCkx
🎧Beats by Dr. Dre Studio3 — https://amzn.to/3mUxgx8