最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how to Route parent to child component in react router dom - Stack Overflow

programmeradmin0浏览0评论

I have an admin dashboard you can check to hear

I want to that if the admin clicks in user(You can see in the screenshot) then it will render the user page and other pages I trying to implement Nested Routeing But not working please if anyone can help it will be appreciated

if someone knows how to render child ponents and implement them in App.js Please Tell me

Admin.js

import React from 'react'
import { useState } from "react";
import  "../AllStyle.css";
import {FaHouseUser, FaTasks, FaUser, FaBars} from "react-icons/fa"
import { NavLink } from 'react-router-dom'
import { AnimatePresence, motion } from "framer-motion";
import SidebarMenu from './SidebarMenu'

const routes = [
  {
  path: "/user",
  name: "Users",
  icon: <FaHouseUser />,
  },
  {
    path: "/project",
    name: "Project",
    icon: <FaTasks />,
    },
    {
      path: "/login",
      name: "Logout",
      icon: <FaUser />,
    },
];


const Admin = ({ children }) => {
  const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);
  const showAnimation = {
    hidden: {
      width: 0,
      opacity: 0,
      transition: {
        duration: 0.5,
      },
    },
    show: {
      opacity: 1,
      width: "auto",
      transition: {
        duration: 0.5,
      },
    },
  };

  return (
    <>
      <div className="main-container">
        <motion.div
          animate={{
            width: isOpen ? "200px" : "45px",

            transition: {
              duration: 0.5,
              type: "spring",
              damping: 10,
            },
          }}
          className={`sidebar `}
        >
          <div className="top_section">
            <AnimatePresence>
              {isOpen && (
                <motion.h1
                  variants={showAnimation}
                  initial="hidden"
                  animate="show"
                  exit="hidden"
                  className="logo"
                >
                  Evalue portal
                </motion.h1>
              )}
            </AnimatePresence>

            <div className="bars">
              <FaBars onClick={toggle} />
            </div>
          </div>
          <section className="routes">
            {routes.map((route, index) => {
              if (route.subRoutes) {
                return (
                  <SidebarMenu
                    setIsOpen={setIsOpen}
                    route={route}
                    showAnimation={showAnimation}
                    isOpen={isOpen}
                  />
                );
              }

              return (
                <NavLink
                  to={route.path}
                  key={index}
                  className="link"
                  // activeClassName="active"
                >
                  <div className="icon">{route.icon}</div>
                  <AnimatePresence>
                    {isOpen && (
                      <motion.div
                        variants={showAnimation}
                        initial="hidden"
                        animate="show"
                        exit="hidden"
                        className="link_text"
                      >
                        {route.name}
                      </motion.div>
                    )}
                  </AnimatePresence>
                </NavLink>
              );
            })}
          </section>
        </motion.div>

        <main>{children}</main>
      </div>
    </>
  );
};

export default Admin

App.js

import {  BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './ponents/Home';
import Navbar from './ponents/Navbar';
import Contact from './ponents/Contact';
import Service from './ponents/Service'
import Login from './ponents/Login';
// Redirect to their dashboar
import Admin from './ponents/dashboard/admin/Admin';
import Employee from './ponents/dashboard/Employee';
import Publisher from './ponents/dashboard/Publisher';
//Toast error message show
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import Reset from './ponents/Reset';
import Newpassword from './ponents/Newpassword';

//admin Routes
import User from './ponents/dashboard/admin/pages/User'
import Project from './ponents/dashboard/admin/pages/Project'

function App() {


  return ( 
    <div>
  
      <Router>
    <Navbar/> 
    <Routes>
    
    <Route exact path="/" element={<Home/>} />
      <Route exact path="/service" element={<Service/>} />
      <Route exact path="/contact" element={<Contact/>} />
      <Route exact path="/login" element={<Login/>} />
      <Route exact path="/reset" element={<Reset/>} />
      <Route exact path="/reset/:token" element={<Newpassword/>} />
      {/* Redirect to their dashboard */}
      <Route exact path="/admin" element={<Admin/>} />
      <Route exact path="/employee" element={<Employee/>} />
      <Route exact path="/publisher" element={<Publisher/>} />
    </Routes>
    </Router>

    {/* admin routes*/}
      <Router>
        {/* <Admin>  For the admin children route to render children*/}
        <Routes>
        <Route  path="/user" element={<User />} />
        <Route  path="/project" element={<Project />} />
          </Routes>
          {/* </Admin> */}
      </Router>
    <ToastContainer
    position="top-right"
    autoClose={4000}
    hideProgressBar={false}
    newestOnTop={false}
    closeOnClick
    rtl={false}
    pauseOnFocusLoss
    draggable
    pauseOnHover
    />
    </div>
  );
}

export default App;

I have an admin dashboard you can check to hear

I want to that if the admin clicks in user(You can see in the screenshot) then it will render the user page and other pages I trying to implement Nested Routeing But not working please if anyone can help it will be appreciated

if someone knows how to render child ponents and implement them in App.js Please Tell me

Admin.js

import React from 'react'
import { useState } from "react";
import  "../AllStyle.css";
import {FaHouseUser, FaTasks, FaUser, FaBars} from "react-icons/fa"
import { NavLink } from 'react-router-dom'
import { AnimatePresence, motion } from "framer-motion";
import SidebarMenu from './SidebarMenu'

const routes = [
  {
  path: "/user",
  name: "Users",
  icon: <FaHouseUser />,
  },
  {
    path: "/project",
    name: "Project",
    icon: <FaTasks />,
    },
    {
      path: "/login",
      name: "Logout",
      icon: <FaUser />,
    },
];


const Admin = ({ children }) => {
  const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);
  const showAnimation = {
    hidden: {
      width: 0,
      opacity: 0,
      transition: {
        duration: 0.5,
      },
    },
    show: {
      opacity: 1,
      width: "auto",
      transition: {
        duration: 0.5,
      },
    },
  };

  return (
    <>
      <div className="main-container">
        <motion.div
          animate={{
            width: isOpen ? "200px" : "45px",

            transition: {
              duration: 0.5,
              type: "spring",
              damping: 10,
            },
          }}
          className={`sidebar `}
        >
          <div className="top_section">
            <AnimatePresence>
              {isOpen && (
                <motion.h1
                  variants={showAnimation}
                  initial="hidden"
                  animate="show"
                  exit="hidden"
                  className="logo"
                >
                  Evalue portal
                </motion.h1>
              )}
            </AnimatePresence>

            <div className="bars">
              <FaBars onClick={toggle} />
            </div>
          </div>
          <section className="routes">
            {routes.map((route, index) => {
              if (route.subRoutes) {
                return (
                  <SidebarMenu
                    setIsOpen={setIsOpen}
                    route={route}
                    showAnimation={showAnimation}
                    isOpen={isOpen}
                  />
                );
              }

              return (
                <NavLink
                  to={route.path}
                  key={index}
                  className="link"
                  // activeClassName="active"
                >
                  <div className="icon">{route.icon}</div>
                  <AnimatePresence>
                    {isOpen && (
                      <motion.div
                        variants={showAnimation}
                        initial="hidden"
                        animate="show"
                        exit="hidden"
                        className="link_text"
                      >
                        {route.name}
                      </motion.div>
                    )}
                  </AnimatePresence>
                </NavLink>
              );
            })}
          </section>
        </motion.div>

        <main>{children}</main>
      </div>
    </>
  );
};

export default Admin

App.js

import {  BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './ponents/Home';
import Navbar from './ponents/Navbar';
import Contact from './ponents/Contact';
import Service from './ponents/Service'
import Login from './ponents/Login';
// Redirect to their dashboar
import Admin from './ponents/dashboard/admin/Admin';
import Employee from './ponents/dashboard/Employee';
import Publisher from './ponents/dashboard/Publisher';
//Toast error message show
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import Reset from './ponents/Reset';
import Newpassword from './ponents/Newpassword';

//admin Routes
import User from './ponents/dashboard/admin/pages/User'
import Project from './ponents/dashboard/admin/pages/Project'

function App() {


  return ( 
    <div>
  
      <Router>
    <Navbar/> 
    <Routes>
    
    <Route exact path="/" element={<Home/>} />
      <Route exact path="/service" element={<Service/>} />
      <Route exact path="/contact" element={<Contact/>} />
      <Route exact path="/login" element={<Login/>} />
      <Route exact path="/reset" element={<Reset/>} />
      <Route exact path="/reset/:token" element={<Newpassword/>} />
      {/* Redirect to their dashboard */}
      <Route exact path="/admin" element={<Admin/>} />
      <Route exact path="/employee" element={<Employee/>} />
      <Route exact path="/publisher" element={<Publisher/>} />
    </Routes>
    </Router>

    {/* admin routes*/}
      <Router>
        {/* <Admin>  For the admin children route to render children*/}
        <Routes>
        <Route  path="/user" element={<User />} />
        <Route  path="/project" element={<Project />} />
          </Routes>
          {/* </Admin> */}
      </Router>
    <ToastContainer
    position="top-right"
    autoClose={4000}
    hideProgressBar={false}
    newestOnTop={false}
    closeOnClick
    rtl={false}
    pauseOnFocusLoss
    draggable
    pauseOnHover
    />
    </div>
  );
}

export default App;
Share Improve this question edited Mar 24, 2022 at 9:28 TheDeveloperGuy asked Mar 24, 2022 at 8:07 TheDeveloperGuyTheDeveloperGuy 1612 gold badges5 silver badges15 bronze badges 13
  • Is there a reason you are rendering two routers? Can you clarify what the issue is and what you are trying to acplish. What isn't working as expected? – Drew Reese Commented Mar 24, 2022 at 8:37
  • i want acplish if admin click on any link like project (You can see in this Screenshot) then it will render page – TheDeveloperGuy Commented Mar 24, 2022 at 9:25
  • You can use <Outlet /> ponent inside the Home ponent. Then the children ponents will be rendered automatic. reactrouter./docs/en/v6/api#outlet – Henrique Ramos Commented Mar 24, 2022 at 10:54
  • can you please give, my edit code – TheDeveloperGuy Commented Mar 24, 2022 at 17:47
  • OK. And what is the issue? I suspect rendering two routers is likely the cause for any issues you are seeing. Can you clarify what the issue is? What isn't working as expected? – Drew Reese Commented Mar 24, 2022 at 23:19
 |  Show 8 more ments

3 Answers 3

Reset to default 1

Modify Admin.js to Use Outlet Since Admin serves as a layout for the nested routes, use the Outlet ponent from react-router-dom to indicate where child ponents should be rendered.

    import React, { useState } from "react";
import { FaHouseUser, FaTasks, FaUser, FaBars } from "react-icons/fa";
import { NavLink, Outlet } from "react-router-dom";
import { AnimatePresence, motion } from "framer-motion";
import "../AllStyle.css";

const routes = [
  { path: "/admin/user", name: "Users", icon: <FaHouseUser /> },
  { path: "/admin/project", name: "Project", icon: <FaTasks /> },
  { path: "/login", name: "Logout", icon: <FaUser /> },
];

const Admin = () => {
  const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);

  const showAnimation = {
    hidden: { width: 0, opacity: 0, transition: { duration: 0.5 } },
    show: { opacity: 1, width: "auto", transition: { duration: 0.5 } },
  };

  return (
    <div className="main-container">
      {/* Sidebar */}
      <motion.div
        animate={{
          width: isOpen ? "200px" : "45px",
          transition: { duration: 0.5, type: "spring", damping: 10 },
        }}
        className="sidebar"
      >
        <div className="top_section">
          <AnimatePresence>
            {isOpen && (
              <motion.h1
                variants={showAnimation}
                initial="hidden"
                animate="show"
                exit="hidden"
                className="logo"
              >
                Evalue Portal
              </motion.h1>
            )}
          </AnimatePresence>
          <div className="bars">
            <FaBars onClick={toggle} />
          </div>
        </div>
        <section className="routes">
          {routes.map((route, index) => (
            <NavLink to={route.path} key={index} className="link">
              <div className="icon">{route.icon}</div>
              <AnimatePresence>
                {isOpen && (
                  <motion.div
                    variants={showAnimation}
                    initial="hidden"
                    animate="show"
                    exit="hidden"
                    className="link_text"
                  >
                    {route.name}
                  </motion.div>
                )}
              </AnimatePresence>
            </NavLink>
          ))}
        </section>
      </motion.div>

      {/* Main Content: This will render the nested routes */}
      <main>
        <Outlet />
      </main>
    </div>
  );
};

export default Admin;

Modify App.js for Nested Routing Ensure that child routes for Admin are defined within a parent route.

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./ponents/Home";
import Navbar from "./ponents/Navbar";
import Contact from "./ponents/Contact";
import Service from "./ponents/Service";
import Login from "./ponents/Login";
import Admin from "./ponents/dashboard/admin/Admin";
import Employee from "./ponents/dashboard/Employee";
import Publisher from "./ponents/dashboard/Publisher";
import Reset from "./ponents/Reset";
import Newpassword from "./ponents/Newpassword";

// Admin Pages (Children of Admin)
import User from "./ponents/dashboard/admin/pages/User";
import Project from "./ponents/dashboard/admin/pages/Project";

import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

function App() {
  return (
    <Router>
      <Navbar />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/service" element={<Service />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="/login" element={<Login />} />
        <Route path="/reset" element={<Reset />} />
        <Route path="/reset/:token" element={<Newpassword />} />
        <Route path="/employee" element={<Employee />} />
        <Route path="/publisher" element={<Publisher />} />

        {/* ✅ Nested Routes for Admin */}
        <Route path="/admin" element={<Admin />}>
          <Route path="user" element={<User />} />
          <Route path="project" element={<Project />} />
        </Route>
      </Routes>

      <ToastContainer
        position="top-right"
        autoClose={4000}
        hideProgressBar={false}
        newestOnTop={false}
        closeOnClick
        rtl={false}
        pauseOnFocusLoss
        draggable
        pauseOnHover
      />
    </Router>
  );
}

export default App;

You can use Outlet ponent.

Example of implementation:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import { AuthProvider } from "./utils/context/auth";

ReactDOM.render(
  <React.StrictMode>
      <BrowserRouter>
        <AuthProvider>
          <App />
        </AuthProvider>
      </BrowserRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

app.js

import React from "react";
import { Route, Routes } from "react-router-dom";
import { useAuth } from "./utils/context/auth";
import "react-toastify/dist/ReactToastify.css";
import "./index.css";
import LoginPage from "./app/pages/Auth/Login";
import NotFoundPage from "./app/pages/NotFound/NotFound";
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

const App = () => {
  const { checkingSession, isAuthenticated } = useAuth();

  if (checkingSession) {
    return <Loading />;
  }

  return (
    <>
      <Navbar />
      <Routes>
        {checkingSession || !isAuthenticated ? (
          <Route path={"/"} element={<LoginPage />} />
        ) : (
          <Route path="/admin" element={<Layout />}>
            <Route path={"/admin"} element={<Dashboard />} />
            <Route path={"/admin/project"} element={<Project />} />
          </Route>
        )}
        <Route path={"/*"} element={<NotFoundPage />} />
        <ToastContainer
          position="top-right"
          autoClose={4000}
          hideProgressBar={false}
          newestOnTop={false}
          closeOnClick
          rtl={false}
          pauseOnFocusLoss
          draggable
          pauseOnHover
      />
      </Routes>
    </>
  );
};

export default App;

layout.js

    import React from 'react'
import { useState } from "react";
import  "../AllStyle.css";
import {FaHouseUser, FaTasks, FaUser, FaBars} from "react-icons/fa"
import { NavLink } from 'react-router-dom'
import { AnimatePresence, motion } from "framer-motion";
import SidebarMenu from './SidebarMenu'

import { Outlet } from "react-router-dom";
// The outlet ponent

const routes = [
  {
  path: "/user",
  name: "Users",
  icon: <FaHouseUser />,
  },
  {
    path: "/project",
    name: "Project",
    icon: <FaTasks />,
    },
    {
      path: "/login",
      name: "Logout",
      icon: <FaUser />,
    },
];


const Private = ({ children }) => {
  const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);
  const showAnimation = {
    hidden: {
      width: 0,
      opacity: 0,
      transition: {
        duration: 0.5,
      },
    },
    show: {
      opacity: 1,
      width: "auto",
      transition: {
        duration: 0.5,
      },
    },
  };

  return (
    <>
      <div className="main-container">
        <motion.div
          animate={{
            width: isOpen ? "200px" : "45px",

            transition: {
              duration: 0.5,
              type: "spring",
              damping: 10,
            },
          }}
          className={`sidebar `}
        >
          <div className="top_section">
            <AnimatePresence>
              {isOpen && (
                <motion.h1
                  variants={showAnimation}
                  initial="hidden"
                  animate="show"
                  exit="hidden"
                  className="logo"
                >
                  Evalue portal
                </motion.h1>
              )}
            </AnimatePresence>

            <div className="bars">
              <FaBars onClick={toggle} />
            </div>
          </div>
          <section className="routes">
            {routes.map((route, index) => {
              if (route.subRoutes) {
                return (
                  <SidebarMenu
                    setIsOpen={setIsOpen}
                    route={route}
                    showAnimation={showAnimation}
                    isOpen={isOpen}
                  />
                );
              }

              return (
                <NavLink
                  to={route.path}
                  key={index}
                  className="link"
                  // activeClassName="active"
                >
                  <div className="icon">{route.icon}</div>
                  <AnimatePresence>
                    {isOpen && (
                      <motion.div
                        variants={showAnimation}
                        initial="hidden"
                        animate="show"
                        exit="hidden"
                        className="link_text"
                      >
                        {route.name}
                      </motion.div>
                    )}
                  </AnimatePresence>
                </NavLink>
              );
            })}
          </section>
        </motion.div>

        <main>
          <Outlet /> // The outlet ponent
        </main>
      </div>
    </>
  );
};

export default Private

Basically the Outlet will render the routes you put inside the /admin route. More info in this link

For your use case, you can use <Outlet/> ponent to render child routes. As per React Router v7 docs:

Renders the matching child route of a parent route or nothing if no child route matches

For details you can check: https://api.reactrouter./v7/functions/react_router.Outlet.html

发布评论

评论列表(0)

  1. 暂无评论