<HeaderContainer>
<Switch>
<Route exact path='/counters' component={ParentCounterContainer}/>
<Route exact path='/about' component={AboutContainer} />
<Route exact path='/' component={HomeContainer}/>
<Route component={ErrorContainer} />
</Switch>
</HeaderContainer>
How can I wrap all routes except ErrorContainer in HeaderContainer?
import React from 'react';
import {Route, Redirect} from 'react-router-dom';
const CustomRoute = ({
component: Component,
...rest
}) => (
<Header />
<Route {...rest} component={(props) => {return <Component {...props} />}}/>
)
export default CustomRoute;
Try Custom Routing like this. It may work.
App router
<Switch>
<CustomRoute exact path='/counters' component={ParentCounterContainer}/>
<CustomRoute exact path='/about' component={AboutContainer} />
<CustomRoute exact path='/' component={HomeContainer}/>
<Route component={ErrorContainer} />
</Switch>
Simply put the 404 page component Route outside the HeaderContainer.
<Switch>
<HeaderContainer>
<Route exact path='/counters' component={ParentCounterContainer}/>
<Route exact path='/about' component={AboutContainer} />
<Route exact path='/' component={HomeContainer}/>
</HeaderContainer>
<Route component={ErrorContainer} />
<Switch>
Related
I have a following index file -
<BrowserRouter>
<Routes>
<Route path="/" element={Home}
<Route element={Navigation}
</Routes>
</BrowserRouter>
I have multiple routes which I have to load So For that I have written a component:
const Navigation = () => {
<>
<Route path="/not-available-primary" element={NotAvaliable}/>
<Route path="/not-available-Secondary" element={Avaliable}/>
<Route path="/available-primary" element={Primary}/>
<Route path="/available-Secondary" element={Secondary}/>
<Route path="/direct-debit-primary" element={DirectDBB}/>
<Route path="/direct-debit-secondary" element={DirectDBBSecondary}/>
</>
}
But here, it does not render the component and gives no routes matched for location.
How do I fix this ?
You have to give a Component to the element prop, like this:
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/*" element={<Navigation />} />
</Routes>
</BrowserRouter>
and
const Navigation = () => {
return (<>
<Route path="/not-available-primary" element={<NotAvaliable />}/>
<Route path="/not-available-Secondary" element={<Avaliable />}/>
<Route path="/available-primary" element={<Primary />}/>
<Route path="/available-Secondary" element={<Secondary />}/>
<Route path="/direct-debit-primary" element={<DirectDBB />}/>
<Route path="/direct-debit-secondary" element={<DirectDBBSecondary />}/>
</>)
}
or
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/*">
<Route path="not-available-primary" element={<NotAvaliable />}/>
<Route path="not-available-Secondary" element={<Avaliable />}/>
<Route path="available-primary" element={<Primary />}/>
<Route path="available-Secondary" element={<Secondary />}/>
<Route path="direct-debit-primary" element={<DirectDBB />}/>
<Route path="direct-debit-secondary" element={<DirectDBBSecondary
/>}/>
</Route>
</Routes>
</BrowserRouter>
Note that in the seconds solution (nested routes) I erased the "/".
Documentation here
in your index file
<Route path="/" compoment={Home}
if "Navigation" is your class
const Navigation = () => {
return (
<>
<Routes>
<Route path="/not-available-primary" component={NotAvaliable}/>
<Route path="/not-available-Secondary" component={Avaliable}/>
<Route path="/available-primary" component={Primary}/>
<Route path="/available-Secondary" component={Secondary}/>
<Route path="/direct-debit-primary" component={DirectDBB}/>
<Route path="/direct-debit-secondary" component={DirectDBBSecondary}/>
</Routes>
</>
)
}
Issue
It's unclear which version of react-router-dom you are trying to use. version 4/5 or 6, but you've syntax issues for either. The route rendering the Navigation component needs a path with a trailing "*" character to be matched at the root/base level so the descendent routes can then also be matched and rendered.
Using react-router-dom#5
Use the Switch component instead of the Routes component. The Route components use the component (or render or children function props). The home path "/" must exactly match in order for any other route to be matched when the path isn't exactly "/", e.g. "/not-available-primary".
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="*" component={Navigation} />
</Switch>
</BrowserRouter>
...
const Navigation = () => {
<Switch>
<Route path="/not-available-primary" component={NotAvaliable} />
<Route path="/not-available-Secondary" component={Avaliable} />
<Route path="/available-primary" component={Primary} />
<Route path="/available-Secondary" component={Secondary} />
<Route path="/direct-debit-primary" component={DirectDBB} />
<Route path="/direct-debit-secondary" component={DirectDBBSecondary} />
</Switch>
};
Using react-router-dom#6
All Route components can only be rendered by a Routes component or another Route component in the case of route nesting. The Route component API changed significantly and there is now only a single element prop taking a ReactNode, a.k.a. JSX, as a value. In RRDv6 all routes are now always exactly matched and use a route ranking system; there is no longer an exact prop for Route components.
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<Navigation />} />
</Routes>
</BrowserRouter>
...
const Navigation = () => {
<Routes>
<Route path="/not-available-primary" element={<NotAvaliable />} />
<Route path="/not-available-Secondary" element={<Avaliable />} />
<Route path="/available-primary" element={<Primary />} />
<Route path="/available-Secondary" element={<Secondary />} />
<Route path="/direct-debit-primary" element={<DirectDBB />} />
<Route path="/direct-debit-secondary" element={<DirectDBBSecondary />} />
</Routes>
};
At the first use <Switch> in Navigation component :
const Navigation = () => {
<Switch>
<Route path="/not-available-primary" component={NotAvaliable}/>
<Route path="/not-available-Secondary" component={Avaliable}/>
<Route path="/available-primary" component={Primary}/>
<Route path="/available-Secondary" component={Secondary}/>
<Route path="/direct-debit-primary" component={DirectDBB}/>
<Route path="/direct-debit-secondary" component={DirectDBBSecondary}/>
</Switch>
}
so, add the component to Route:
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/login" exact component={LoginForm} />
<Route component={Navigation} />
</Switch>
</BrowserRouter>
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 a beginner with react-router-dom, there are two different states in the code when I dont use Navigate from react-router-dom , it works properly , but when I use the Navigate function it renders a blank page.
I have confirmed that all the individual components work and render properly.
Please help me solve this issue .
Here is my code of App.js without Navigate
import React from 'react';
import { Container } from '#material-ui/core';
import { BrowserRouter , Route , Routes , Navigate } from 'react-router-dom'
import PostDetails from './components/PostDetails/PostDetails';
import Home from './components/Home/Home';
import Navbar from './components/Navbar/Navbar';
import Auth from './components/Auth/Auth';
const App = () => {
const user = JSON.parse(localStorage.getItem('profile'));
return (
<BrowserRouter>
<Container maxWidth="lg">
<Navbar />
<Routes>
<Route exact path="/" element ={<Home/>} />
<Route path="/auth" element={<Auth/>} />
<Route path="/posts" exact element={<Home/>} />
<Route path="/posts/search" exact element={<Home/>} />
<Route path="/posts/:id" exact element={<PostDetails/>} />
<Route path="/auth" exact element={() => (!user ? <Auth /> : <Navigate to="/posts" />)} />
</Routes>
</Container>
</BrowserRouter>
)
};
export default App;
Here is my code of App.js with Navigate which does not works
import React from 'react';
import { Container } from '#material-ui/core';
import { BrowserRouter , Route , Routes , Navigate } from 'react-router-dom'
import PostDetails from './components/PostDetails/PostDetails';
import Home from './components/Home/Home';
import Navbar from './components/Navbar/Navbar';
import Auth from './components/Auth/Auth';
const App = () => {
const user = JSON.parse(localStorage.getItem('profile'));
return (
<BrowserRouter>
<Container maxWidth="lg">
<Navbar />
<Routes>
<Route path="/" exact component={() => <Navigate replace to="/posts" />} />
<Route path="/posts" exact element={<Home/>} />
<Route path="/posts/search" exact element={<Home/>} />
<Route path="/posts/:id" exact element={<PostDetails/>} />
<Route path="/auth" exact element={() => (!user ? <Auth /> : <Navigate replace to="/posts" />)} />
</Routes>
</Container>
</BrowserRouter>
)
};
export default App;
In react-router-dom#6 the Route components's element prop takes only a ReactNode, a.k.a. JSX. You've one route taking a component prop which is invalid, and two routes passing a function.
Use the element prop and pass JSX only.
Note that there is also no longer any exact prop, in RRDv6 all routes are always exactly matched.
<BrowserRouter>
<Container maxWidth="lg">
<Navbar />
<Routes>
<Route path="/" element={<Navigate replace to="/posts" />} />
<Route path="/posts" element={<Home />} />
<Route path="/posts/search" element={<Home />} />
<Route path="/posts/:id" element={<PostDetails />} />
<Route
path="/auth"
element={!user ? <Auth /> : <Navigate replace to="/posts" />}
/>
</Routes>
</Container>
</BrowserRouter>
If you are trying to protect these "/posts*" routes then it is common to create a layout route to handle redirecting to the login route or render the protected routes.
Example:
const AuthLayout = ({ authenticated }) =>
authenticated
? <Outlet />
: <Navigate to="/auth" replace />;
...
<BrowserRouter>
<Container maxWidth="lg">
<Navbar />
<Routes>
<Route element={<AuthLayout authenticated={!!user} />}>
<Route path="/posts" element={<Home />} />
<Route path="/posts/search" element={<Home />} />
<Route path="/posts/:id" element={<PostDetails />} />
</Route>
<Route path="/" element={<Navigate replace to="/posts" />} />
<Route
path="/auth"
element={!user ? <Auth /> : <Navigate replace to="/posts" />}
/>
</Routes>
</Container>
</BrowserRouter>
use element props instead component
<Route path="/" exact component={() => <Navigate replace to="/posts" />} />
<Route path="/" exact element={() => <Navigate replace to="/posts" />
I have created routes in app.js and /, /create-receipt and /login routes are working fine but if I go to /signup route or any other route below /login it loads the Login component, if I remove login and signup component then the routes are working perfectly.
App.js:-
<Router>
<Header/>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/create-receipt" component={CreateReceipt} />
<Route Path="/login" component={Login} />
<Route Path="/signup" component={Signup} />
<Route path="/fast-food-receipt" exact component={FastFoodReceipt} />
<Route path="/fast-food-receipt/receipt-one" component={FastFoodReceiptOne} />
<Route path="/fast-food-receipt/receipt-two" component={FastFoodReceiptTwo} />
<Route path="/fast-food-receipt/receipt-three" component={FastFoodReceiptThree} />
<Route path="/fast-food-receipt/receipt-four" component={ReceiptFour} />
<Route path="/fast-food-receipt/receipt-five" component={FastFoodReceiptFive} />
<Route path="" component={NotFound} />
</Switch>
<Footer/>
</Router>
Login.js:-
const Login = () =>{
return(
login page
)
}
export default Login;
Signup.js:-
const Signup = () =>{
return(
signup page
)
}
export default Signup;
NOTE:- issue is coming when i use route component like this
<Route Path="/signup" component={Signup} />
<Route Path="/login" component={Login} />
working fine when i am using route component in this way:-
<Route exact path="/"><Home /></Route>
<Route path="/login"><Login /></Route>
<Route path="/signup"><Signup /></Route>
can some one tell why it is happening
I have a React site with three different routes, and I want it to automatically display the first one, which is called Home, when a user enters the site. Here is the code I have in App.js:
<Router>
<Navigation />
<Switch>
<Route path="/hypstats" exact component={() => <Home />} />
<Route path="/hypstats/auctions" exact component={() => <AuctionViewer />} />
<Route path="/hypstats/bazaar" exact component={() => <BazaarViewer />} />
</Switch>
</Router>
And here is the Navigation component:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import "../App.css"
function Navigation(props) {
return (
<div className="navbar">
<Link className="navlink" to="/hypstats">HypStats</Link>
<Link className="navlink" to="/hypstats/auctions">Auctions</Link>
<Link className="navlink" to="/hypstats/bazaar">Bazaar</Link>
</div>
)
}
export default Navigation;
To make any view as the default view you could include the following into your Navigation
<Route path="/" exact component={() => <Home />} />
Or you could write as below:
<Redirect from="/" to="/hypstats"} />
<Router>
<Navigation />
<Switch>
<Route path="/hypstats" exact component={() => <Home />} />
<Route path="/hypstats/auctions" exact component={() => <AuctionViewer />} />
<Route path="/hypstats/bazaar" exact component={() => <BazaarViewer />} />
**<Route path="/" exact component={() => <Home />} />**
</Switch>
</Router>
We use the basename attribute to tell the basename of the site. So that in the next routes, we would not have to set basename, here /hypstats, manually every time we add a new route. React Router manages it by itself.
<Router basename="/hypstats">
<Navigation />
<Switch>
<Route path="/" exact component={() => <Home />} />
<Route path="/auctions" exact component={() => <AuctionViewer />} />
<Route path="/bazaar" exact component={() => <BazaarViewer />} />
</Switch>
</Router>
Run this somewhere in your App component.
history.push({
pathname: '/hypstats',
});
You are using "react-router-dom" so you can import:
import { useHistory } from "react-router-dom";
And then you can use:
const history = useHistory();
So whenever user enters your react application it will open the '/hypstats'.
You could do this in a useEffect.