Nested routing is not working in React Router v6

ghz 6months ago ⋅ 83 views

I am trying react router v6. As per react training blog, I have created object of routing and passed to useRoutes():

function SomeOtherElement() {
  return <h1>add user</h1>;
}

const routes = [
  {
    path: 'app',
    element: <DashboardLayout />,
    children: [
      { path: 'account', element: <AccountView /> },
      {
        path: 'users', element: <UserListView />, 
        children: [
          { path: 'add', element: <SomeOtherElement /> }
        ]
      },
      { path: 'dashboard', element: <DashboardView /> },
      { path: 'products', element: <ProductListView /> },
      { path: 'settings', element: <SettingsView /> },
      { path: '*', element: <Navigate to="/404" /> }
    ]
  }];

const routing = useRoutes(routes);

But the nested routing is not working. As you can see in above object, I want to create URL and render the UI for user "add" functionality.

URL in the browser is getting updated correctly to http://localhost:3000/app/users/add but UI is not updating.

Answers

The issue you're encountering with nested routing in React Router v6 is likely due to missing or incorrect implementation of Outlet in your route components. In React Router v6, the Outlet component is used to render child routes. Ensure that you have placed the Outlet component in your parent route components where you want the nested routes to be rendered.

Here's an updated version of your code with the Outlet component added:

import { useRoutes, Outlet, Navigate } from 'react-router-dom';
import DashboardLayout from './DashboardLayout';
import AccountView from './AccountView';
import UserListView from './UserListView';
import DashboardView from './DashboardView';
import ProductListView from './ProductListView';
import SettingsView from './SettingsView';

function SomeOtherElement() {
  return <h1>add user</h1>;
}

function UserListWithOutlet() {
  return (
    <div>
      <UserListView />
      <Outlet />
    </div>
  );
}

const routes = [
  {
    path: 'app',
    element: <DashboardLayout />,
    children: [
      { path: 'account', element: <AccountView /> },
      {
        path: 'users', element: <UserListWithOutlet />, 
        children: [
          { path: 'add', element: <SomeOtherElement /> }
        ]
      },
      { path: 'dashboard', element: <DashboardView /> },
      { path: 'products', element: <ProductListView /> },
      { path: 'settings', element: <SettingsView /> },
      { path: '*', element: <Navigate to="/404" /> }
    ]
  }
];

const routing = useRoutes(routes);

function App() {
  return (
    <div>
      {routing}
    </div>
  );
}

export default App;

In the code above:

  1. A UserListWithOutlet component is created, which includes the UserListView and an Outlet. This component will render the UserListView and any nested routes.
  2. The path: 'users' route now uses the UserListWithOutlet component instead of UserListView directly.

By ensuring the Outlet component is used correctly, the nested routes should render as expected. This way, when you navigate to http://localhost:3000/app/users/add, the SomeOtherElement component will be rendered within the UserListView.