Search code examples
reactjsreact-router-dom

how to pass default component to child components using BrowserRouter, Switch and Route of react-router-dom@5.2.0 and react@17?


I made one admin default layout and wanted to use this component into every admin route component, but there is issue that my react version is 17 and react-router-dom version is 5.2.0, so this reason (may be i am wrong, because i am beginner) i haven't option to use like 'Outlet' (react-router-dom@6+). Please guide me to pass like :

(Route.js)

<BrowserRouter>
 <Routes>
  <Route path="/admin/dashboard" element={AdminDefaultLayout}>
   <Route path="/admin/dashboard" element={Dashboard} />
   <Route path="/admin/category" element={Category} />
  </Route>
 </Routes>
</BrowserRouter>

(AdminDefaultLayout.jsx)

<>
<div className="container">
 <Header />
 <Sidebar />
 <main>
  <Outlet />
 </main>
 <Footer />
</div>
</>

this is my package.json file

{
 "name": "magicbox",
 "version": "1.3.0",
 "private": true,
 "dependencies": {
    "axios": "^1.5.1",
    "google-map-react": "^1.1.7",
    "http-proxy-middleware": "^0.19.2",
    "isomorphic-fetch": "^3.0.0",
    "lax.js": "^1.2.5",
    "react": "^17.0.2",
    "react-accessible-accordion": "^3.3.4",
    "react-countup": "^4.4.0",
    "react-dom": "^17.0.2",
    "react-modal-video": "^1.2.8",
    "react-owl-carousel3": "^2.2.5",
    "react-router-dom": "^5.2.0",
    "react-scripts": "^5.0.1",
    "react-visibility-sensor": "^5.1.1",
    "sass": "^1.51.0"
  },
}

and this is my route.jsx file

import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

import HomeFour from "./components/pages/HomeFour";
import Login from "./components/pages/Login";

import AdminDefaultLayout from "./components/AdminDefaultLayout";
import Dashboard from "./components/pages/admin/Dashboard";

const renderNavigation = () => {
  if (!(window.location.pathname === '/login' || 
        window.location.pathname === '/signup' || 
        window.location.pathname === '/coming-soon' || 
        window.location.pathname === '/error-404' || 
        window.location.pathname === '/admin/dashboard'|| 
        window.location.pathname === '/admin/category')
    ) {
        return <Navigation />;
      }
}

const AppRouter = () => {
 const existToken = localStorage.getItem('ACCESS_TOKEN');
 return (
  <>
    { existToken ? 
      (
       <Router>
        <Switch>
         <Route path="/admin/dashboard" render={(props) => <AdminDefaultLayout><Dashboard {...props} /></AdminDefaultLayout>}/>
        </Switch>
       </Router>
      ) : (
       <Router>
       {renderNavigation()}
        <Switch>
         <Route path="/login" exact component={Login} />
         <Route path="/" exact component={HomeFour} />
        </Switch>
       </Router>
       ) 
    }
   </>
  )
}

export default AppRouter;

(AdminDefaultLayout.jsx)

<>
 <div className="container">
  <Header />
  <Sidebar />
  <main>
    <Switch></Switch>
  </main>
  <Footer />
 </div>
</>

so, after doing this, only AdminDefaultLayout component is seen in page, no Dashboard component seen, please guide me. thanks for the help.

updated: there is not react-router found in my package.json file, i am apologized for wrong information, this is my first question so, my query is not in formatted too. but i got the solution after research on it. i am updating the answer, please see below and thanks for guide me @Drew Reese.

Solution

  • After sometimes spend in research i got my solution from this reference link, layouts in react-router

    In react 17 and react-router-dom@5.2.0 we can do this as given below:

    in Routes.jsx file

    import React from "react";
    import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
    
    import HomeFour from "./components/pages/HomeFour";
    import Login from "./components/pages/Login";
    
    import AdminDefaultLayout from "./components/AdminDefaultLayout";
    import Dashboard from "./components/pages/admin/Dashboard";
    import ProtectedRoute from "./ProtectedRoute";
    
    const renderNavigation = () => {
      if (!(window.location.pathname === '/login' || 
            window.location.pathname === '/signup' || 
            window.location.pathname === '/coming-soon' || 
            window.location.pathname === '/error-404' || 
            window.location.pathname === '/admin/dashboard'|| 
            window.location.pathname === '/admin/category')
        ) {
            return <Navigation />;
          }
    }
    
    const AppRouter = () => {
     const existToken = localStorage.getItem('ACCESS_TOKEN');
     return (
      <>
        { existToken ? 
          (
           <Router>
            <Switch>
             <ProtectedRoute path="/admin/dashboard" exact component={Dashboard} layout={AdminDefaultLayout} />
            </Switch>
           </Router>
          ) : (
           <Router>
           {renderNavigation()}
            <Switch>
             <Route path="/login" exact component={Login} />
             <Route path="/" exact component={HomeFour} />
            </Switch>
           </Router>
           ) 
        }
       </>
      )
    }
    
    export default AppRouter;
    

    i made ProtectedRoute component to set 'AdminDefaultLayout' for admin routes, as given below code:

    in ProtectedRoute.jsx file

    import React from "react";
    import { Route, Redirect } from "react-router-dom";
    
    const ProtectedRoute = ({ component: Component, layout: Layout, ...rest}) => {
        const existToken = localStorage.getItem('ACCESS_TOKEN');
    
        return (
            <>
                <Route {...rest} render = {(props) => existToken ? ( <Layout {...props} > <Component key={props.location.key} {...props} /> </Layout>) : (<Redirect to="/login" />)} />
            </>
        );
    };
    
    export default ProtectedRoute;
    

    after this in AdminDefaultLayout i passed children object into it, to show that default layout in particular admin pages/components which is given below:

    in AdminDefaultLayout.jsx file

    const AdminDefaultLayout = ({children}) => {
     return (
      <>
       <div className="container">
        <Header />
        <Sidebar />
        <main>
         {children}
        </main>
        <Footer />
       </div>
      </>
     );
    };
    
    export default AdminDefaultLayout;
    

    and this is resolved my issue where i was stuck. thanks for your guidance.