'React router doesn't work in my private admin layout and normal user layout

I'm new at react and I want to show my admin dashboard privately whit Route but just first Route work and the other Route's component don't shown. this is my code:

<Routes>
      <Route path="/admin" element={<PrivateLayout />}>
        <Route path="/dashboard" exact element={<Dashboard />} />
      </Route>

      <Route exact path='/' element={<MainLayouts />}>
        <Route  path="/" element={<Course />} />
        <Route  path="/login" element={<Login />} />
        <Route  path="/register" element={<Register />} />
        <Route  path="/course/:id" element={<SingleCourse />} />
        <Route  path="/archive" element={<Archive />} />
        <Route  path="/logout" element={<Logout />} />
        <Route  path="*"  element={<NotFound />} />
      </Route>

    </Routes>

by the mean just PrivateLayout in path of '/dashboard' and the MainLayouts in the path of '/' shown and login, register , ... dont shown in their own path.

and also MainLayouts codes are:

import React, { Fragment } from "react";
import Header from "./../common/headers";
import TopNav from "./../Navs/TopNav";
import MainNav from "./../Navs/MainNav";
import Footer from './../common/Footers';
import { useLocation } from 'react-router';

const MainLayouts = ({children}) => {
  
  const location = useLocation()
  
  return (
    <Fragment>
      <div className="landing-layer">
        <div className="container">
          <TopNav />
          {location.pathname === "/" ? <Header /> : null}
        </div>
      </div>

      <MainNav />

      <main id="home-page">
              <div className="container">{children}</div>
      </main>

      <Footer/>
 
    </Fragment>
  );
};

export default MainLayouts;

and PrivateLayout codes are:

import React from "react";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
import Helmet from "react-helmet";
import AdminTopNav from "../admin/AdminTopNav";
import AdminSidebar from "../admin/AdminSidebar";

const PrivateLayout = ({ children }) => {
    const user = useSelector((state) => state.user);
    return (
        <div id="wrapper">
            <Helmet>
                <title> dashboard </title>
            </Helmet>
            <nav
                className="navbar navbar-inverse navbar-fixed-top"
                role="navigation"
            >
                <div className="navbar-header">
                    <Link className="navbar-brand" to="/dashboard">
                        admin dashboard
                    </Link>
                </div>

                <AdminTopNav user={user} />

                <AdminSidebar />
            </nav>
            <div id="page-wrapper">{children}</div>
        </div>
    );
};

export default PrivateLayout;


Solution 1:[1]

Issue

The issue is that your layout components are rendering the children prop instead of an Outlet component for the nested Route components to be rendered into. I also found the use of the Outlet component confusing when upgrading from react-router-dom@5.

Outlet

An <Outlet> should be used in parent route elements to render their child route elements. This allows nested UI to show up when child routes are rendered. If the parent route matched exactly, it will render a child index route or nothing if there is no index route.

Outlet components are commonly used in what are called layout routes.

Layout Route

Solution

Replace the rendering of the children prop with the Outlet component.

import { Outlet, useLocation } from 'react-router';

const MainLayouts = () => {
  const location = useLocation();
  
  return (
    <Fragment>
      <div className="landing-layer">
        <div className="container">
          <TopNav />
          {location.pathname === "/" ? <Header /> : null}
        </div>
      </div>

      <MainNav />

      <main id="home-page">
        <div className="container">
          <Outlet />
        </div>
      </main>

      <Footer/>
    </Fragment>
  );
};

export default MainLayouts;

...

import { Link, Outlet } from "react-router-dom";

const PrivateLayout = () => {
  const user = useSelector((state) => state.user);
  return (
    <div id="wrapper">
      <Helmet>
        <title> dashboard </title>
      </Helmet>
      <nav
        className="navbar navbar-inverse navbar-fixed-top"
        role="navigation"
      >
        <div className="navbar-header">
          <Link className="navbar-brand" to="/dashboard">
            admin dashboard
          </Link>
        </div>

        <AdminTopNav user={user} />

        <AdminSidebar />
      </nav>
      <div id="page-wrapper">
        <Outlet />
      </div>
    </div>
  );
};

export default PrivateLayout;

Once the layout routes are rendering an Outlet component you'll see why "/dashboard" isn't a valid path under "/admin".

Error

Absolute route path "/dashboard" nested under path "/admin" is not valid. An absolute child route path must start with the combined path of all its parent routes.

I will assume at this point you want all the "/admin" routes to be nested under it, so use either absolute path "/admin/dashboard" or relative path "dashboard".

<Routes>
  <Route path="/admin" element={<PrivateLayout />}>
    <Route path="dashboard" element={<Dashboard />} />
  </Route>

  <Route path="/" element={<MainLayouts />}>
    <Route index element={<Course />} />
    <Route path="login" element={<Login />} />
    <Route path="register" element={<Register />} />
    <Route path="course/:id" element={<SingleCourse />} />
    <Route path="archive" element={<Archive />} />
    <Route path="logout" element={<Logout />} />
    <Route path="*" element={<NotFound />} />
  </Route>
</Routes>

Edit react-router-doesnt-work-in-my-private-admin-layout-and-normal-user-layout

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Drew Reese