Home > database >  Sidebar implementation: [Routes] is not a <Route> component. All component children of <Rou
Sidebar implementation: [Routes] is not a <Route> component. All component children of <Rou

Time:07-22

I'm trying to implement a SideBar but keep it excluded from the /login route.

My code seems to be a mess at the moment, and I'm not quite sure why I'm getting this error at the moment.

This is what I'm trying to do at the moment:

App.js:

<Router>
    <div className="App">
        <SideBar
            onCollapse={(inactive) => {
                console.log(inactive);
                setInactive(inactive);
            }}
        />
        <div className={`container ${inactive ? "inactive" : ""}`}>
            {menuItems.map((menu, index) => (
                <>
                    <Route key={menu.name} exact={menu.exact} path={menu.to}>
                        <h1>{menu.name}</h1>
                    </Route>
                    {menu.subMenus && menu.subMenus.length > 0
                        ? menu.subMenus.map((subMenu, i) => (
                            <Route key={subMenu.name} path={subMenu.to}>
                                <h1>{subMenu.name}</h1>
                            </Route>
                        ))
                        : null}
                </>
            ))}
            <Routes>
                <Route exact path="/login" element={<Login />} />
                <Route exact path='/' element={<ProtectedRoutes />}>
                    <Routes>
                        <Route exact path='/main' element={<Main />} />
                    </Routes>
                </Route>
            </Routes>
        </div>
    </div>
</Router>

menuItems:

export const menuItems = [
    {
        name: "Dashboard",
        exact: true,
        to: "/",
        iconClassName: "bi bi-speedometer2",
    },
    {
        name: "Content",
        exact: true,
        to: `/content`,
        iconClassName: "bi bi-speedometer2",
        subMenus: [
            { name: "Courses", to: "/content/courses" },
            { name: "Videos", to: "/content/videos" },
        ],
    },
    { name: "Design", to: `/design`, iconClassName: "bi bi-vector-pen" },
    {
        name: "Content 2",
        exact: true,
        to: `/content-2`,
        iconClassName: "bi bi-speedometer2",
        subMenus: [
            { name: "Courses", to: "/content-2/courses" },
            { name: "Videos", to: "/content-2/videos" },
        ],
    },
    { name: "Design 2", to: `/design-2`, iconClassName: "bi bi-vector-pen" },
    { name: "Design 3", to: `/design-3`, iconClassName: "bi bi-vector-pen" },
    { name: "Design 4", to: `/design-4`, iconClassName: "bi bi-vector-pen" },
];

CodePudding user response:

This issue is here:

<Routes>
  <Route exact path="/login" element={<Login />} />
  <Route exact path='/' element={<ProtectedRoutes />}>
    <Routes> // <-- here!!
      <Route exact path='/main' element={<Main />} />
    </Routes>
  </Route>
</Routes>

If you are just trying to nest routes then you don't need an additional Routes component. The Routes component would only be needed if rendering a component rendering descendent routes.

Remove the Routes:

<Routes>
  <Route path="/login" element={<Login />} />
  <Route element={<ProtectedRoutes />}>
    <Route path='/main' element={<Main />} />
  </Route>
</Routes>

If you want to exclude UI components on certain routes then create another layout route component like you did with ProtectedRoutes.

Example:

import { Outlet } from 'react-router-dom';

const SideBarLayout = ({ inactive, setInactive }) => (
  <>
    <SideBar
      onCollapse={(inactive) => {
        console.log(inactive);
        setInactive(inactive);
      }}
    />
    <div className={`container ${inactive ? "inactive" : ""}`}>
      {menuItems.map((menu) => (
        <React.Fragment key={menu.name}>
          <Link to={menu.to}>
            <h1>{menu.name}</h1>
          </Link>
          {menu?.subMenus?.map((subMenu) => (
            <Link key={subMenu.name} to={subMenu.to}>
              <h1>{subMenu.name}</h1>
            </Link>
          ))}
        </React.Fragment>
      ))}
    </div>
    <Outlet />
  </>
);

...

<Routes>
  <Route path="/login" element={<Login />} />
  ... other routes w/o SideBar ...

  <Route element={<SideBarLayout {...{ inactive, setInactive }} />}>
    ... other routes with SideBar ...

    <Route element={<ProtectedRoutes />}>
      <Route path='/main' element={<Main />} />
      ... other protected routes ...
    </Route>
  </Route>
</Routes>

CodePudding user response:

Try to wrap your between Router tags, like this:

<Router>
         <Route exact path="/login" element={<Login />} />
                <Route exact path='/' element={<ProtectedRoutes />}>
                    <Routes>
                        <Route exact path='/main' element={<Main />} />
                    </Routes>
                </Route>
      </Router>
  • Related