Home > Back-end >  Route inside route not work for me in react
Route inside route not work for me in react

Time:01-10

I have a website that I'm building and an admin dashboard that I want to go to. I have a page that has an <Outlet/> inside it, and only when I go to the admin-dashboard address it works, but if I add a path, it leaves me from the page where I have the <Outlet/>.

This is my page with <Outlet/> code:

const Layout = (props) => {
  const [open, setOpen] = useState(false);
  const dreWidth = window.screen.width > 1000 ? open ? 300 : 100 : null 
  return (
    <Box>
      {props.adminPath && <MiniDrawer open={open} setOpen={setOpen} logged={props.logCheck} auth={props.auth}/>}
      <Box
        component='main'
        style={{ flexGrow: 1, padding: 3, width: `calc(100% - ${dreWidth}px)` , transition : '0.5s' , float: 'left' }}
      >
        <Toolbar style={{ minHeight: "1.875rem" }} />
        <Box style={{ margin: "1rem 2rem" }}>
          <Outlet />
        </Box>
      </Box>
    </Box>
  );
};

export default Layout;

This is main with the Routers :

const MainPage = () => {
  const dispatch = useDispatch();
  const auth = useSelector((state) => state.auth.auth);
  const token = useSelector((state) => state.auth.token);
  const users = useSelector((state) => state.users.users);
  const { pathname } = useLocation()

  useEffect(() => {
    dispatch(LoadUser())
    dispatch(getAllUsers())
  }, [dispatch])

  let logCheck = token
  let user = users.find(user => user.id === auth.id)

  let adminPath = pathname === '/admin-dashboard'

  return (
    <>
      <Box>
      {!adminPath && <Header logged={logCheck} user={user} auth={auth}/>}
        <Routes>
          <Route path="/" element={<HomePage />} />
          <Route path="/about" element={<AboutPage />} />
          <Route path="/contact" element={<Contact />} />
          <Route path="/join-to-course" element={logCheck ? <Navigate to='/'/> :<JoinToCourse />} />
          <Route path="/join" element={logCheck ? <Navigate to='/'/> : <MainJoinToCourse />} />
          <Route path="/join/:orderId" element={logCheck ? <Navigate to='/'/> : <PaymentPage />} />
          <Route path="/login" element={logCheck ? <Navigate to='/'/> : <LoginPage />} />
          <Route path="admin-dashboard" element={logCheck ? <Layout adminPath={adminPath} user={user} auth={auth}/> : <Navigate to='/' />}>
            <Route path="" element={<Dashboard />}/>
            <Route path="home-page" element={<HomePageContents />}/>
          </Route>
        </Routes>
      </Box>
      <Box>
        <BackToTop />
      </Box>
      {!adminPath && <Footer />}
    </>
  );
};

export default MainPage;

CodePudding user response:

Doesn't matter I just changed the code from this :

let adminPath = pathname === '/admin-dashboard'

to this :

let adminPath = pathname.includes('/admin-dashboard')

now its work

CodePudding user response:

As I understand your question/issue you appear to want to conditionally render the Header component on non-admin routes.

Create another layout that renders Header and an Outlet, similar to the existing Layout component.

Non-Admin layout

const Layout = () => {
  const auth = useSelector((state) => state.auth.auth);
  const token = useSelector((state) => state.auth.token);
  const users = useSelector((state) => state.users.users);

  const user = users.find(user => user.id === auth.id);

  return (
    <>
      <Header logged={token} user={user} auth={auth}/>
      <Box style={{ margin: "1rem 2rem" }}>
        <Outlet />
      </Box>
      <Box>
        <BackToTop />
      </Box>
      <Footer />
    </>
  );
};

Admin layout

const AdminLayout = () => {
  const auth = useSelector((state) => state.auth.auth);
  const token = useSelector((state) => state.auth.token);
  const users = useSelector((state) => state.users.users);

  const [open, setOpen] = useState(false);

  const dreWidth = window.screen.width > 1000 ? open ? 300 : 100 : null 
  return (
    <Box>
      <MiniDrawer open={open} setOpen={setOpen} logged={token} auth={auth} />
      <Box
        component='main'
        style={{
          flexGrow: 1,
          padding: 3,
          width: `calc(100% - ${dreWidth}px)`,
          transition : '0.5s',
          float: 'left'
        }}
      >
        <Toolbar style={{ minHeight: "1.875rem" }} />
        <Box style={{ margin: "1rem 2rem" }}>
          <Outlet />
        </Box>
      </Box>
    </Box>
  );
};

It seems you are also using a token value stored in state to conditionally render a routed component or the Navigate component. For simplicity of routing I'd suggest also creating protected layout routes as well.

ProtectedRoute

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

const ProtectedRoute = () => {
  const token = useSelector((state) => state.auth.token);

  if (token === undefined) {
    return null;
  }

  return token ? <Outlet> : <Navigate to='/' replace />;
};

AnonymousRoute

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

const AnonymousRoute = () => {
  const token = useSelector((state) => state.auth.token);

  if (token === undefined) {
    return null;
  }

  return token ? <Navigate to='/' replace /> : <Outlet>;
};

Main

const MainPage = () => {
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(LoadUser());
    dispatch(getAllUsers());
  }, [dispatch]);

  return (
    <Box>
      <Routes>
        <Route element={<Layout />}>
          <Route path="/" element={<HomePage />} />
          <Route path="/about" element={<AboutPage />} />
          <Route path="/contact" element={<Contact />} />
          <Route element={<AnonymousRoute />}>
            <Route path="/join-to-course" element={<JoinToCourse />} />
            <Route path="/join" element={<MainJoinToCourse />} />
            <Route path="/join/:orderId" element={<PaymentPage />} />
            <Route path="/login" element={<LoginPage />} />
          </Route>
        </Route>
        <Route element={<ProtectedRoute />}>
          <Route path="admin-dashboard" element={<AdminLayout />}>
            <Route index element={<Dashboard />} />
            <Route path="home-page" element={<HomePageContents />} />
          </Route>
        </Route>
      </Routes>
    </Box>
  );
};
  • Related