I am using react-router-dom v6. I want my Login page to be rendered without the Sidebar and Topbar components. How to do it?
function App() {
return (
<Router>
<Container>
<Sidebar />
<Content>
<Topbar />
<MainContent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/users/:id" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<Product />} />
<Route path="/newProduct" element={<NewProduct />} />
<Route path="/login" element={<Login />} />
</Routes>
</MainContent>
</Content>
</Container>
</Router>
);
}
I don't want my login page to render inside the MainContent but taking the whole page without Sidebar and Topbar.
I tried moving the Routes upper and have the login route above the sidebar but there is an error Error: [Sidebar] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
Since SideBar and TopBar appear to be part of a "layout", and you want a different "layout" specifically for "/login" then I suggest abstracting the container components into layout components. Each layout container should render an Outlet for their respective nested routes.
const AppLayout = () => (
<Container>
<Sidebar />
<Content>
<Topbar />
<MainContent>
<Outlet />
</MainContent>
</Content>
</Container>
);
const LoginLayout = () => (
<Container>
<Content>
<MainContent>
<Outlet />
</MainContent>
</Content>
</Container>
);
...
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<AppLayout />}>
<Route index element={<Home />} />
<Route path="users" element={<UserList />} />
<Route path="users/:id" element={<User />} />
<Route path="newUser" element={<NewUser />} />
<Route path="products" element={<ProductList />} />
<Route path="products/:id" element={<Product />} />
<Route path="newProduct" element={<NewProduct />} />
</Route>
<Route path="/login" element={<LoginLayout />}>
<Route index element={<Login />} />
</Route>
</Routes>
</Router>
);
}
function App() {
return (
<Router>
<Container>
{
Login || <Sidebar />
}
<Content>
{
Login || <Topbar />
}
<MainContent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/users/:id" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<Product />} />
<Route path="/newProduct" element={<NewProduct />} />
<Route path="/login" element={<Login />} />
</Routes>
</MainContent>
</Content>
</Container>
</Router>
);
}
try conditional rendering. It works for me!
Related
How Outlet should be defined in react-router v6.4.
Here is my code
function Layout() {
return (
<div>
<Navbar />
<Outlet />
<Footer />
</div>
);
}
Import the values from the router and use the following structure
import { BrowserRouter, Routes, Route } from "react-router-dom";
<BrowserRouter>
<HeaderSignIn />
<Routes>
<Route path="/" element={<HomePageSignIn />} />
<Route path="/sign-in" element={<SigIn />} />
<Route path="/login" element={<LogIn />} />
<Route path="/admin_login" element={<Login />} />
<Route path="/explore" element={<Explore />} />
<Route path="/shop" element={<ShopView />} />
<Route path="/about" element={<About />} />
<Route path="/job" element={<PleaseLogIn />} />
<Route path="/new-shop-item" element={<PleaseLogIn />} />
<Route path="/new-shop" element={<PleaseLogIn />} />
</Routes>
<Footer />
</BrowserRouter>
Follow the ReactRouter Documentation for more information
In my code, there are many imports (38 import components) and routes(38 routes) so can simplify those into a few imports and routes is there any way available...???
function App() { return (
<Router>
<SideBar>
<Routes>
<Route path="/Architecture" element={<ReactJs_Architecture />} />
<Route path="/JSX" element={<ReactJs_JSX />} />
<Route path="/Components" element={<ReactJs_Components />} />
<Route path="/Styling" element={<ReactJs_Styling />} />
<Route path="/Properties" element={<ReactJs_Properties />} />
<Route path="/EventManagement" element={<ReactJs_EventManagement />} />
<Route path="/StateManagement" element={<ReactJs_StateManagement />} />
<Route path="/Redux" element={<ReactJs_Redux />} />
<Route path="/Animation" element={<ReactJs_Animation />} />
<Route path="/Home" element={<NodeJs_Home />} />
<Route path="/Node_Introduction" element={<Node_Introduction/>} />
<Route path="/EnvironmentSetup" element={<NodeJs_EnvironmentSetup />} />
<Route path="/REPLTerminal" element={<NodeJs_REPLTerminal />} />
<Route path="/PackageManager" element={<NodeJs_PackageManager />} />
<Route path="/Buffers" element={<NodeJs_Buffers />} />
<Route path="/Streams" element={<NodeJs_Streams />} />
<Route path="/WebModule" element={<NodeJs_WebModule />} />
<Route path="/ScalingApplications" element={<NodeJs_ScalingApplications />} />
<Route path="/Packaging" element={<NodeJs_Packaging />} />
<Route path="*" element= { < not found />} />
</Routes>
</SideBar>
</Router>
);
}
export default App;
If your items are long always try to create an array and list all your routes there like this
const ROUTE_PATHS = {
PRICING: "/pricing",
ACTIONS: "/actions",
};
const routeItems = [
{
name: "Pricing",
path: ROUTE_PATHS.PRICING,
Component: Pricing,
},
{
name: "Bulk Actions",
path: ROUTE_PATHS.ACTIONS,
Component: Actions,
},
];
And now add a loop to iterate over all the routes
<Routes>
{routeItems.map(item => {
const { Component } = item;
return (
<Route
key={item.name}
path={item.path}
element={
<Component />
}
/>
);
})}
</Routes>
Now it made simple.
I have looked at the previous questions and googled for the answer and I think I almost know what the issue in here is, but don't know how to solve it.
return (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
{admin && (
<>
<Topbar />
<div className="container">
<Sidebar />
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/user/:userId" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/product/:productId" element={<Product />} />
<Route path="/newproduct" element={<NewProduct />} />
</div>
</>
)}
</Routes>
</Router>
Please tell me how to setup the topar and slidebar components here.
Requesting my fellow coders to look at this one and thanks in advance.
The error is clear, you only can use the <Route /> tag, and remove the <div className="container"> also.
Try this:
return (
<>
<Topbar />
<Sidebar />
<Router>
<Routes>
<Route path="/login" element={<Login />} />
{admin && (
<>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/user/:userId" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/product/:productId" element={<Product />} />
<Route path="/newproduct" element={<NewProduct />} />
</>
)}
</Routes>
</Router>
</>
)
Or you can import your TOPBAR and SIDEBAR components inside every other component.
to render a login page without a topbar and sidebar create a private router component and wrap it around all the routes you want to render a topbar and sidebar with
use react-outlet
here is what worked for me
app.js
import "./App.css";
import Sidebar from "./Components/Sidebar/Sidebar";
import TopBar from "./Components/TopBar/TopBar";
import Home from "./Pages/Home/Home";
import UserList from "./Pages/UserList/UserList";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import User from "./Pages/User/User";
import NewUser from "./Pages/NewUser/NewUser";
import ProductList from "./Pages/ProductList/ProductList";
import Product from "./Pages/Product/Product";
import NewProduct from "./Pages/NewProduct/NewProduct";
import { useSelector } from "react-redux";
import Login from "./Pages/Login/Login";
import { Outlet } from "react-router-dom";
const SidebarLayout = () => (
<>
<TopBar />
<div className="container">
<Sidebar />
<Outlet />
</div>
</>
);
function App() {
// const admin = useSelector((state) => state.user.currentUser.isAdmin);
const admin = JSON.parse(
JSON.parse(localStorage.getItem("persist:root")).user
).currentUser.isAdmin;
return (
<BrowserRouter>
<Routes>
<Route element={<SidebarLayout />}>
<Route index element={<Home />} />
<Route exact path="/users" element={<UserList />} />
<Route exact path="/users/:id" element={<User />} />
<Route exact path="/newUser" element={<NewUser />} />
<Route exact path="/products" element={<ProductList />} />
<Route exact path="/products/:id" element={<Product />} />
<Route exact path="/newProduct" element={<NewProduct />} />
</Route>
<Route exact path="/login" element={<Login />} />
</Routes>
</BrowserRouter>
);
}
export default App;
import React from "react";
import { Router, Routes, Route } from "react-router-dom";
import Home from "./Home";
import UserList from "./UserList";
import NewUser from "./NewUser";
import ProductList from "./ProductList";
import Product from "./Product";
import NewProduct from "./NewProduct";
import Login from "./Login";
const AppRoute = () => {
return (
<>
{admin ? (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/user/:userId" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/product/:productId" element={<Product />} />
<Route path="/newproduct" element={<NewProduct />} />
</Routes>
</Router>
) : (
<Router>
<Routes>
<Route path="/" element={<Login />} />
</Routes>
</Router>
)}
</>
);
};
export default AppRoute;
const admin = JSON.parse(
JSON.parse(localStorage.getItem("persist:root")).user
).currentUser.isAdmin;
return (
<Router>
<>
<Topbar />
<div className="container">
<Sidebar />
<Routes>
<Route
path="/login"
element={admin ? <Navigate to="/" /> : <Login />}
/>
<Route exact path="/" element={<Home />}></Route>
<Route path="/users" element={<UserList />}></Route>
<Route path="/user/:userId" element={<User />}></Route>
<Route path="/newUser" element={<NewUser />}></Route>
<Route path="/products" element={<ProductList />}></Route>
<Route path="/product/:productId" element={<Product />}></Route>
<Route path="/newproduct" element={<NewProduct />}></Route>
</Routes>
</div>
</>
</Router>
); ```
I am learning from udemy but that course is from v5.I dont know what is equivalent to render and how to send props with it ? Also, in bottom of the code if element is undefined it should go to "NotFound" but its not working too.
<Routes>
<Route
exact
path="/home"
render={(props) => (
<ProductList
{...props}
products={this.state.products}
currentCategory={this.state.currentCategory}
info={productInfo}
addToCart={this.addToCart}
/>
)}
></Route>
<Route exact path="/cart" element={<CartList />} />
<Route element={<NotFound />} />
</Routes>
<Routes>
<Route exact path="/" element={<ProductList
{...this.props}
products={this.state.products}
currentCategory={this.state.currentCategory}
info={productInfo}
addToCart={this.addToCart}
/>}></Route>
<Route exact path="/cart" element={<CartList />} />
<Route path="*"element={<NotFound />} />
</Routes>
I solved.
In the v6 you can pass props directly to the element. No need to use render anymore
<Route exact path="/cart" element={<CartList {...props} />} />
How do I add 404 - Not Found page in React with React-Router?
Here's my attempt:
// routes.tsx
export const routes = [
{
path: '/students',
render: (props: any) => <List {...props} title={`Students`} />,
},
{
path: '/teachers',
render: (props: any) => <List {...props} title={`Teachers`} />,
},
]
// App.tsx
import { routes } from './routes'
function App() {
const routeComponents = routes.map(({ path, render }, key) => (
<Route exact path={path} render={render} key={key} />
))
return (
<ThemeProvider theme={theme}>
<CSSReset />
<Suspense fallback={<Loader />}>
<Router>
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
<Layout>{routeComponents}</Layout>
{/* <Route component={NotFound} /> */}
<Route path="*" component={NotFound} />
</Switch>
</Router>
</Suspense>
</ThemeProvider>
)
}
export default App
But I can't see my custom "404 - Not Found" page when I go to 'http://localhost:3000/nothing', but <Layout /> component.
What I am doing wrong?
Stack: TypeScript, React#v16.13.1, react-router-dom#v5.1.2
404 Page on react does not need to have a path as it needs to be a page rendered when roue is not found between the paths of the pages you already have. It should work this way:
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
{routeComponents()}
<Route component={NotFound} />
</Switch>
Left blank path="". It will render 404 page.
see -
<Route path="" component={PageNotFound} />
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
This can fix
https://stackoverflow.com/a/64651959/16361679
return (
<ThemeProvider theme={theme}>
<CSSReset />
<Suspense fallback={<Loader />}>
<Router>
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
<Layout>
<Switch>
{routeComponents}
<Route path="*" component={NotFound} />
<Switch>
</Layout>
</Switch>
</Router>
</Suspense>
</ThemeProvider>
)