could you please tell me why component is not loaded when router changes
router file
export default function ForceLayoutRouter() {
return (
<Router>
<div>
<Switch>
<Route path="/calender" exact>
<ForceCalender />
</Route>
<Route path="/home" exact>
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
link file
<Menu theme="dark" mode="inline" defaultSelectedKeys={["1"]}>
<Menu.Item key="1" icon={<UserOutlined />}>
<NavLink to={`/home`} exact>
Home ex
</NavLink>
</Menu.Item>
<Menu.Item key="2" icon={<CalendarOutlined />}>
<NavLink to={`/calender`}>Calender</NavLink>
</Menu.Item>
<Menu.Item key="3" icon={<LogoutOutlined />}>
Logout
</Menu.Item>
</Menu>
when I click home or calender link it change the router but component is not loaded.
here is my code
https://codesandbox.io/s/elated-black-3yozm?file=/src/components/layout.js:730-1230
You should wrap your app within a single Router. Try remove Router in your ForceLayoutRouter.
export default function ForceLayoutRouter() {
return (
<div>
<Switch>
<Route path="/calender" exact>
<ForceCalender />
</Route>
<Route path="/home" exact>
<Home />
</Route>
</Switch>
</div>
);
}
Here's the working codesandbox: https://codesandbox.io/s/crazy-grass-tnq63?file=/src/layout2.js
Related
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>
); ```
the problem is the following. in the app.js is spelled out Routes and the home component. the home contains a navbar that navigates the site, only if you go to any page, it is drawn on top of the home. And if you switch to the home itself, it will be duplicated. Articles on the internet did not help, as did the addition of exact in route path.
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home/>}/>
<Route path="/settings/" element={<Settings/>}/>
<Route path="/login/" element={<Login/>}/>
<Route path="/register/" element={<Register/>}/>
</Routes>
<Home/>
</div>
)
home
export default class Home extends Component {
render() {
return (
<div>
<NavBar/>
<ChatMenu/>
</div>
);
}
}
an example of how it is written in the navbar
export const NavBar = () => {
return (<div className="navbar-cm">
<div className="nav_element">
<Link to="/home">
<img src={homeIMG} className="nav_element"/>
</Link>
</div>
and a few more similar ones
</div>);
};
Issue
You are rendering the Home component again once outside the routes, this is why it's rendered with all routes including twice when on the "/home" path that renders Home.
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home />} />
<Route path="/settings/" element={<Settings />} />
<Route path="/login/" element={<Login />} />
<Route path="/register/" element={<Register />} />
</Routes>
<Home /> // <-- always rendered below routed content
</div>
)
}
Solution
Remove the Home component that is out on its own outside the routes.
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home />} /> // <-- now only Home component rendered
<Route path="/settings/" element={<Settings />} />
<Route path="/login/" element={<Login />} />
<Route path="/register/" element={<Register />} />
</Routes>
</div>
)
}
Remove <Home /> from the router:
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home/>}/>
<Route path="/settings/" element={<Settings/>}/>
<Route path="/login/" element={<Login/>}/>
<Route path="/register/" element={<Register/>}/>
</Routes>
</div>
)
I am using use location to hide the navbar if the pathname name is /admin, /employee, /publisher. but I got an error saying that Error: useLocation() may be used only in the context of a <Router> component.
This is My App.js
import { BrowserRouter as Router, Routes, Route, useLocation } from 'react-router-dom';
import Navbar from './components/Navbar';
function App() {
const location = useLocation()
return (
<>
<UserState>
<Router>
{!["/admin", "/employee", "/publisher"].includes(location.pathname) && <Navbar/>} //For to hide the navbar if the pathname is /admin, /employee, /publisher
<Routes onUpdate={() => window.scrollTo(0, 0)}>
<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 />} />
<Route path="*" element={<NoteFound/>} />
{/* admin pages */}
<Route path="/admin" element={<Admin />}>
<Route path="add-project" element={<Addproject />} />
<Route path="all-user" element={<AllUser />} />
</Route>
{/* Publisher dasboard */}
<Route path="/publisher" element={<Publisher />}>
<Route path="project-status" element={<ProjectStatus />} />
<Route path="allpublise" element={<Allpublise />} />
</Route>
</Route>
</Routes>
</Router>
</UserState>
</>
);
}
export default App;
The useLocation hook (and all other react-router-dom hooks) need a router above it in the ReactTree so that a routing context is available.
2 options:
Move the Router component up the tree and wrap the App component so it can use the useLocation hook.
import { BrowserRouter as Router } from 'react-router-dom';
...
<Router>
<App />
</Router>
...
import { Routes, Route, useLocation } from 'react-router-dom';
import Navbar from './components/Navbar';
function App() {
const location = useLocation();
return (
<UserState>
{!["/admin", "/employee", "/publisher"].includes(location.pathname) && <Navbar/>}
<Routes onUpdate={() => window.scrollTo(0, 0)}>
<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="*" element={<NoteFound/>} />
{/* admin pages */}
<Route path="/admin" element={<Admin />}>
<Route path="add-project" element={<Addproject />} />
<Route path="all-user" element={<AllUser />} />
</Route>
{/* Publisher dasboard */}
<Route path="/publisher" element={<Publisher />}>
<Route path="project-status" element={<ProjectStatus />} />
<Route path="allpublise" element={<Allpublise />} />
</Route>
</Routes>
</UserState>
);
}
export default App;
Move the useLocation hook down the tree so that it's used within the Router component.
import { Routes, Route, useLocation } from 'react-router-dom';
import Navbar from './components/Navbar';
function App() {
return (
<UserState>
<Router>
<Navbar/>
<Routes onUpdate={() => window.scrollTo(0, 0)}>
<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="*" element={<NoteFound/>} />
{/* admin pages */}
<Route path="/admin" element={<Admin />}>
<Route path="add-project" element={<Addproject />} />
<Route path="all-user" element={<AllUser />} />
</Route>
{/* Publisher dasboard */}
<Route path="/publisher" element={<Publisher />}>
<Route path="project-status" element={<ProjectStatus />} />
<Route path="allpublise" element={<Allpublise />} />
</Route>
</Routes>
</Router>
</UserState>
);
}
export default App;
...
const Navbar = () => {
const location = useLocation();
return !["/admin", "/employee", "/publisher"].includes(location.pathname)
? /* Return navbar JSX here */
: null;
};
useLocation() hook is used to extract the current location from the router.
For this purpose it's need the router context to pass the Location content
So if you want to use this hook, you need to use it in one of the nested components in <Router> Provider.
For your situation, you need to move the hook into the navbar component.
import { useLocation } from 'react-router-dom';
function Navbar() {
const location = useLocation()
if(["/admin", "/employee", "/publisher"].includes(location.pathname))
return <></>
return (
<>
I'm a navbar
</>
);
}
export default Navbar;
I am new to react development. And I want to implement the routing mechanism in my page.
For example, there's component contains routes with the <Home /> and <Login /> component.
function App() {
return (
<div className="App">
<Switch>
<Route exact path="/home">
<Home />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
);
}
The <Home /> component contains a <Navbar /> and a <Switch /> with two <Route />:
Home.js
function Home() {
return (
<div>
<Navbar />
<div>
<Switch>
<Route exact path={`/home`}>
<Menu />
</Route>
<Route path={`/home/temperature`}>
<div>temperature</div>
</Route>
</Switch>
</div>
</div>
)
}
However, I defined the <Link /> in the <Menu /> component as below:
function Menu() {
return (
<div>
<li>
<Link to={`/home/temperature`}>temperature child page</Link>
</li>
</div>
)
}
Originally, the page would displayed the <Home /> component with <Menu /> and <div> temperature </div>
I expected that when I clicked the link (<Link to={/home/temperature}>temperature child page</Link>) then it would replace the <Menu /> component with the only the <div>temperature</div> (Dispalyed the <Navbar/> and <div>temperature</div>, but it could not display anything.
How should I correct it?
Solution:
I finally figure out why I cannot get child component in my js script.
Firstly, I need to wrap the <Switch> with <Router> in <App> component.
Then, by reference this , I realized that I should not specify the exact in <Route path="/home"> to make sure that the nested route can work as well.
function App() {
return (
<div className="App">
<Router>
<div>
<Switch>
<Route path="/home">
<Home />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
</Router>
</div>
);
}
simple routing
<Router>
<Switch>
<Route path={"/home"} exact component={Home} />
</Switch>
</Router>
nested routing
<Router>
<Switch>
<Route path={"/home"} exact component={Home}
<Rout path={"/temperature"} exact component={Temperature} />
</Route>
</Switch>
</Router>
`
I am developing a landing page using React. It should have the same navigation bar for all sections and change only its active state.
In App.js file I have used BrowserRouter that routes to Navigation component. My problem is that that Navigation does not work properly, it does not switch components, it switches only pathname. For example when I press Cabinet, it should switch from Home to Cabinet component. Should I use another router for Navigation or not? What would be the best solution for this?
I have tried to create NavRouter component, where I have placed routers for Navigation.
App.js file:
<BrowserRouter>
<Switch>
<Route path='/' exact component={ Navigation }></Route>
<Route path='/cabinet' component={ Navigation }></Route>
<Route path='/catalog' component={ Navigation }></Route>
<Route path='/company' component={ Navigation }></Route>
<Route path='/contacts' component={ Navigation }></Route>
</Switch>
</BrowserRouter>
Navigation file:
class Navigation extends Component {
render() {
const { classes, location: {pathname}, children } = this.props;
return (
<div>
<MuiThemeProvider theme={color}>
<Fragment>
<nav id="menu">
<ul className="navigation">
<li>
<MenuItem component={Link} to='/' selected={'/' === pathname} className="active menuItem" className={classes.menuItemColor}>
Главная
</MenuItem>
</li>
<li>
<MenuItem component={Link} to='/cabinet' selected={'/cabinet' === pathname} className="menuItem" className={classes.menuItemColor}>
Кабинет
</MenuItem>
</li>
<li>
<MenuItem component={Link} to='/catalog' selected={'/catalog' === pathname} className="menuItem" className={classes.menuItemColor}>
Каталог
</MenuItem>
</li>
<li>
<MenuItem component={Link} to='/company' selected={'/company' === pathname } className="menuItem" className="">
Компания
</MenuItem>
</li>
<li>
<MenuItem component={Link} to='/contacts' selected={'/contacts' === pathname} className="menuItem" className="">
Контакты
</MenuItem>
</li>
</ul>
</nav>
<main className={classes.content}>
{ children }
</main>
</Fragment>
</MuiThemeProvider>
</div>
);
}
}
NavRouter.js file:
<BrowserRouter>
<Navigation>
<Switch>
<Route path='/' exact component={ Navigation }></Route>
<Route path='/home' component={ Home }></Route>
</Switch>
</Navigation>
</BrowserRouter>
you can do the following:
create a file called Routes.js
in Routes.js:
export default () => (
<BrowserRouter>
<Switch>
<Route path='/' exact component={ Home }></Route>
<Route path='/cabinet' component={ Cabinet }></Route>
<Route path='/catalog' component={ Catalog }></Route>
<Route path='/company' component={ Company }></Route>
<Route path='/contacts' component={ Contacts }></Route>
</Switch>
</BrowserRouter>
)
in App.js
import Routes from './Routes';
import Navigation from './Navigation'
//inside render
<Navigation>
<Routes />
</Navigation>
Note: to get the current pathName, you have to use a state management solution like Redux.
Or: if you are not familiar with redux, for now instead of pathname in Navigation component you can use window.location.pathname
Here's the way to you need to do it. Separate the header navigation from the other components.
App.js
<Navigation/>
<BrowserRouter>
<Switch>
<Route path='/' exact component={ Home }></Route>
<Route path='/cabinet' component={ Cabinet }></Route>
<Route path='/catalog' component={ Catalog }></Route>
<Route path='/company' component={ Company }></Route>
<Route path='/contacts' component={ Contacts }></Route>
</Switch>
</BrowserRouter>
I have solved my problem by creating Root.js file, where I have placed my components
class Root extends Component {
render() {
return (
<div>
<MainNavigation />
<TopNav />
{this.props.children}
</div>
);
}
}
And in App.js file I have placed this:
<BrowserRouter>
<Root>
<Route path='/' exact component={ Home } />
<Route path='/cabinet' component={ Cabinet } />
<Route path='/catalog' component={ Catalog } />
<Route path='/company' component={ Company } />
<Route path='/contacts' component={ Contacts } />
</Root>
</BrowserRouter>