I have created a dashboard with a side nav bar and upon selection of each button on the side nav a corresponding page needs to be loaded using react router. I need my default page to be page 1 at load time. and the rest of the pages must be routed on click. On page load only the sidenav is visible and nothing is displayed.
Here is how the page looks on initial render. I have to click on Balance summary to view the page but I want the Balance summary to be loaded by default when the page is loaded the first time.
https://shettysam93.github.io/perpetual-dashboard/
import React from 'react';
import Page1 from '../components/Pages/Page1';
import SideMenu from '../components/SideMenu';
import logo from '../logo.svg';
import './App.css';
import {BrowserRouter as Router,Switch, Route} from 'react-router-dom'
import Transactions from '../components/Pages/Transactions'
import CheckDetails from '../components/Pages/CheckDetails'
import FixedHolding from '../components/Pages/FixedHolding'
import Statement from '../components/Pages/Statement'
import DailyConfirms from '../components/Pages/DailyConfirms'
import Documents from '../components/Pages/Docs'
import AccountInfo from '../components/Pages/AccountInfo'
import Tutorials from '../components/Pages/Tutorials'
import Holiday from '../components/Pages/Holiday'
function App() {
return (
<div>
<Router>
<SideMenu />
<Switch>
<Route path='/' exact component={Page1} />
<Route path='/transaction' exact component={Transactions}/>
<Route path='/details' exact component={CheckDetails}/>
<Route path='/holdings' exact component={FixedHolding}/>
<Route path='/statements' exact component={Statement} />
<Route path='/dailyconfirms' exact component={DailyConfirms} />
<Route path='/documents' exact component={Documents} />
<Route path='/AccountInfo' exact component={AccountInfo} />
<Route path='/Tutorials' exact component={Tutorials} />
<Route path='/Holiday' exact component={Holiday} />
</Switch>
</Router>
</div>
);
}
export default App;
Side Nav: This nav includes the components that will route to the appropriate page which works fine but when the page is loaded the first time only the side nav is displayed and no component is renederd by default.
import React from 'react'
import {Drawer as SideNav,
ListItem,
List,
ListItemIcon,
ListItemText,makeStyles, InputBase} from '#material-ui/core'
import Balance from '#material-ui/icons/PieChartTwoTone';
import Transaction from '#material-ui/icons/ReceiptTwoTone';
import Details from '#material-ui/icons/MonetizationOnTwoTone';
import Holdings from '#material-ui/icons/AccountBalanceWalletTwoTone';
import Statement from '#material-ui/icons/DescriptionTwoTone';
import DailyConf from '#material-ui/icons/DateRangeTwoTone';
import Documents from '#material-ui/icons/AssignmentTwoTone';
import Info from '#material-ui/icons/InfoTwoTone';
import Tutorial from '#material-ui/icons/PlayCircleOutlineTwoTone';
import Holiday from '#material-ui/icons/BeachAccessTwoTone';
import {Link} from 'react-router-dom'
const useStyles = makeStyles({
sideNav:{
display:'absolute',
flexDirection:'column',
width:"70%"
},
searchBox:{
width:"250px",
height: "px",
backgroundColor:"#F1F2F2",
borderRadius:"12px",
outline:"none",
margin:"10px 5px 10px 5px",
border:'1px solid #F1F2F2',
fontFamily:"Roboto",
fontSize:"20px",
textAlign:"center"
},
subHeading: {
width: "62px",
height: "16px",
fontWeight:"700",
fontFamily:"Roboto",
fontSize:"10px",
letterSpacing:"12%",
color:"#818181",
margin: "10px 20px 10px 20px",
position:"relative",
},
listItem:{
position:"relative",
left:"0",
width:"240px",
outline:'none',
textDecoration:'none',
'&:hover':{
width:"240px",
backgroundColor:"#FFD051",
borderRadius:"0px 8px 8px 0px",
cursor: 'pointer',
outline:'none'
}
},
listChild:{
textDecoration:'none',
display:'inline-block',
color:"black "
}
})
function SideMenu() {
const classes = useStyles();
const itemList1 = [{text:"Balance Summary", icon:<Balance />,path:'/'},
{text:"Transactions",icon:<Transaction />,path:'/transaction'},
{text:"Check Details",icon:<Details />,path:'/details'},
{text:"Fixed Term Holdings",icon:<Holdings />,path:'/holdings'}]
const itemList2 = [{text:"Statements", icon:<Statement />,path:'/statements'},
{text:"Daily Confirms",icon:<DailyConf />,path:'/dailyconfirms'},
{text:"Documents",icon:<Documents />,path:'/documents'}]
const itemList3 = [{text:"Account Information", icon:<Info />,path:'/AccountInfo'},
{text:"Tutorials",icon:<Tutorial />,path:'/Tutorials'},
{text:"Holiday Schedule",icon:<Holiday />,path:'/Holiday'}]
return (
<SideNav variant = "permanent" className={classes.sideNav}>
<List>
<ListItem container>
<input type = "text" className={classes.searchBox}/>
</ListItem>
</List>
{/* <InputBase className={classes.searchBox} placeholder=" SEARCH"/> */}
<h6 className={classes.subHeading} >ACCOUNTS</h6>
<List>
{itemList1.map((item,index)=>{
const {text, icon, path} = item
return(
<ListItem button key={text} className={classes.listItem}>
{icon && <ListItemIcon>{icon}</ListItemIcon>}
<Link to={item.path} className={classes.listChild}>
<ListItemText primary={text} />
</Link>
</ListItem>
)
})}
</List>
<h6 className={classes.subHeading}>STATEMENTS</h6>
<List>
{itemList2.map((item,index)=>{
const {text,icon} = item
return(
<ListItem button key={text} className={classes.listItem}>
{icon && <ListItemIcon>{icon}</ListItemIcon>}
<Link to={item.path} className={classes.listChild}>
<ListItemText primary={text} />
</Link>
</ListItem>
)
})}
</List>
<h6 className={classes.subHeading}>RESOURCES</h6>
<List>
{itemList3.map((item,index)=>{
const {text,icon} = item
return(
<ListItem button key={text} className={classes.listItem}>
{icon && <ListItemIcon>{icon}</ListItemIcon>}
<Link to={item.path} className={classes.listChild}>
<ListItemText primary={text} />
</Link>
</ListItem>
)
})}
</List>
</SideNav>
)
}
export default SideMenu
Seems you serve your app from some "/perpetual-dashboard" sub-directory in your github. Try specifying the router's basename prop so paths are relative from this directory.
The base URL for all locations. If your app is served from a
sub-directory on your server, you’ll want to set this to the
sub-directory. A properly formatted basename should have a leading
slash, but no trailing slash.
<Router basename="/perpetual-dashboard">
<SideMenu />
<Switch>
<Route path='/' exact component={Page1} />
<Route path='/transaction' exact component={Transactions}/>
<Route path='/details' exact component={CheckDetails}/>
<Route path='/holdings' exact component={FixedHolding}/>
<Route path='/statements' exact component={Statement} />
<Route path='/dailyconfirms' exact component={DailyConfirms} />
<Route path='/documents' exact component={Documents} />
<Route path='/AccountInfo' exact component={AccountInfo} />
<Route path='/Tutorials' exact component={Tutorials} />
<Route path='/Holiday' exact component={Holiday} />
</Switch>
</Router>
You have to change this route
<Route path='/' exact component={Page1} />
to
<Route path='/' exact component={Page2} />
I am building a website and I don't want to display the navbar in 2 pages. One is the 404 page where I will be giving a redirect button. The other is the landing page of the website where I will be a giving a button which would redirect to the home page of the website. This is my app.js code where I have my routes defined.
import React from "react";
import "./App.css";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Navbar from "./Components/Navbar";
import Home from "./Components/Pages/Home";
import PlanYourTrip from "./Components/Pages/PlanYourTrip";
import AboutUs from "./Components/Pages/AboutUs";
import SafetyMeasures from "./Components/Pages/SafetyMeasures";
import Travel from "./Components/Pages/Travel";
import Error from "./Components/Pages/404";
function App() {
return (
<>
<Router>
<Navbar />
<Switch>
<Route path="/" exact component={Travel} />
<Route path="/home" exact component={Home} />
<Route path="/plan-your-trip" exact component={PlanYourTrip} />
<Route path="/about-us" exact component={AboutUs} />
<Route path="/safety-measures" exact component={SafetyMeasures} />
<Route component={Error} />
</Switch>
</Router>
</>
);
}
export default App;
I want to remove the navbar from <Route path="/" exact component={Travel} /> and <Route component={Error} /> . Please help.
<Navbar /> needs to check to window.location and render empty
See https://reactrouter.com/web/api/Hooks/uselocation
Or create a new component that does the check and render it children
<MayRenderNav><Navbar /></MayRenderNav>
The problem with your code is that <Navbar /> component will load without caring about the route.
You can simply put your <Navbar /> component inside the components you want it to load in and simply leave for others.
To add more context on uke answer you can use the useLocation hook inside your navbar an do something like this
// All the routes you want to exclude
const withouSidebarRoutes = ["/about"];
function Navbar() {
const {pathname} = useLocation();
// Validates if the current pathname includes one the routes you want to hide the sidebar is present on the current url
// If that's true render null instead of the sidebar
if (withouSidebarRoutes.some((item) => pathname.includes(item))) return null;
return (
//your navbar code.
)
}
The includes is useful because if you have nested routes like about/1 it will exclude that one too, use a simple equal if you just want to exclude the about page and not the nested ones.
withouSidebarRoutes.some((item) => pathname === item)
Check the hooks api reference to see what the useLocation can do: https://reactrouter.com/web/api/Hooks/uselocation
Also I have a working sandbox with a sidebar that hides when you're in the about section.
https://codesandbox.io/s/cranky-lewin-p8ozv
This might feel a bit cheat, but it does the trick.
To hide navbar from homepage (path = "/") is quite straight-forward. We can do by the book, use render in "Route".
The tricky part is how to hide from 404 Error page, which doesn't match all other route in your website.
The trick I used is to call useEffect on Error page mount, change style of navbar to display: none;
import React from "react";
import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
import "./styles.css";
const NavBar = () => {
return (
<div className="navbar">
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
<Link to="/error">Error</Link>
</div>
);
};
const Home = () => (
<div>
<h1>This is home</h1>
<ul>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</div>
);
const About = () => <div>About</div>;
const Contact = () => <div>Contact</div>;
const Error = () => {
React.useEffect(() => {
document.getElementsByClassName("navbar")[0].style.display = "none";
}, []);
return (
<div>
<h1>Error</h1>
<Link to="/">Back to home</Link>
</div>
);
};
export default function App() {
return (
<Router>
<Route
render={({ location }) => {
if (location.pathname !== "/") return <NavBar />;
}}
/>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Route component={Error} />
</Switch>
</Router>
);
}
body {
margin: 0;
padding: 0;
}
.App {
font-family: sans-serif;
text-align: center;
}
.navbar {
background: black;
color: white;
padding: 10px 20px;
}
.navbar a {
display: inline-block;
padding: 6px 12px;
text-decoration: none;
color: white;
text-transform: uppercase;
}
Link to sandbox
I have routes like this:
<Provider store={store}>
<BrowserRouter>
<Route path="/" component={App} />
<Route path="/customers" component={Customers} />
<Route path="/tickets" component={Tickets} />
</BrowserRouter>
</Provider>
When the route is /customers I want Customers component inside App component. When the route is /tickets I want Tickets inside App and not Customers. I could check the route using
this.props.location.pathname == '/customers' but that's what the Router is for, right? I shouldn't be checking the route and rendering.
Based on my routes above, I see Customers component below App and not inside it.
The App consists of header and stuff. I don't want to add header code to all my components.
App.js:
<Header style={{ height: '39px', lineHeight: '39px' }}>
<Link to="/home">
<div className="logo" style={{ float: 'left' }}>
<img src="" />
<h2>Appnam</h2>
</div>
</Link>
{navEl}
</Header>
<Content >
// Customer or Tickets component here based on route
</Content>
How do I render the components inside App based on the route.
Assuming you have App as the main component, and you want the Tickets and Customers components inside the App component, you can make use of nested routes
<Provider store={store}>
<BrowserRouter>
<Route path="/" component={App} />
</BrowserRouter>
</Provider>
Inside App component
class App extends React.Component {
render() {
return (
<div>
{/* rest of App code */}
<Route path="/customers" component={Customers} />
<Route path="/tickets" component={Tickets} />
</div>
)
}
}
make use of.
<Provider store={store}>
<BrowserRouter>
<Route exact path="/" component={App} />
<Route exact path="/customers" component={Customers} />
<Route exact path="/tickets" component={Tickets} />
</BrowserRouter>
that will work
I am currently using react-router-dom to create navigation within my web app.
My index.js and App.js look like:
Index.js
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>,
document.getElementById('root')
);
App.js
class App extends React.Component {
render() {
return (
<BrowserRouter>
<div>
<Route exact path ='/' component={Home} />
<Route path ='/container' component={Container} />
<Route path ='/profile' component={ProfilePage} />
</div>
</BrowserRouter>
);
}
}
I idea was that if Home contains the header and the sidebar, it would also keep it for other components like Container and ProfilePage.
My Home's render looks like:
render() {
return (
<div>
<Header />
<div className="App">
<Sidebar />
<Container className="container-comp" />
{this.renderLoggingOutput()}
</div>
</div>
);
}
But when I Link to /profile, it just shows me the ProfilePage component without the header and the sidebar.
Any help?
Put your header outside the routes:
class App extends React.Component {
render() {
return (
<BrowserRouter>
<Header /> <-------- place here or outside the routes at a minimum
<div>
<Route exact path ='/' component={Home} />
<Route path ='/container' component={Container} />
<Route path ='/profile' component={ProfilePage} />
</div>
</BrowserRouter>
);
}
}
I have a similar structure in one of my apps.
the routes look like this:
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Navbar />
<Switch>
<Route exact path='/' component={Dashboard}/>
<Route path='/character/:id' component={CharacterDetails}/>
<Route path='/encounter/:id' component={Encounter}/>
.........
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
The only job of a route is to mount a component. If you want omnipresent components across all routes, treat the routes as children to a base component.
class App extends React.Component {
render() {
<div>
<Header />
<Sidebar />
{this.props.children}
</div>
}
}
const Routes = () => (
<App>
{/* your routes here */}
</App>
)
I'm using react-router v4, no redux. The code example is below:
class MainPage extends Component {
render() {
return (
<div className="MainPage">
<BrowserRouter>
<Switch>
{/* <Route exact path='/' /> */}
<Route path='/signin' component={SignIn}/>
<Route path='/signup' component={SignUp} />
<Redirect from='*' to='/' />
</Switch>
</BrowserRouter>
</div>
);
}
}
When I'm using Link it updates URL in browser but doesn't render anything, nothing happens. When I resfresh, everything becomes fine and component renderes;
export default class Navbar extends Component {
render() {
return (
<div className="navbar">
<BrowserRouter>
<div>
<Link to='/signin'>Sign in</Link>
<Link to='/signup'>Sign up</Link>
</div>
</BrowserRouter>
</div>
);
}
}
I already tried everything, even withRouter(Component), but it says that with router may only be used inside
How can I deal with this?
Here is the working code. As others explained you should use one BrowserRouter. If you want to render your Navbar component all the time then you should place it above Switch but under BrowserRouter hence you need Link there.
const Navbar = () => (
<div className="navbar">
<Link to='/signin'>Sign in</Link>
<Link to='/signup'>Sign up</Link>
</div>
);
class MainPage extends React.Component {
render() {
return (
<div className="MainPage">
<BrowserRouter>
<div>
<Navbar />
<Switch>
{/* <Route exact path='/' /> */}
<Route path='/signin' component={SignIn} />
<Route path='/signup' component={SignUp} />
<Redirect from='*' to='/' />
</Switch>
</div>
</BrowserRouter>
</div>
);
}
}
You should only have a single BrowserRouter component in your tree. The BrowserRouter component holds the shared state the router used to synchronize the URL with the rendered routes. In your situation, you are getting two different versions of router state because you rendering two BrowserRouter components so you should probably render a single BrowserRouter component somewhere higher in your component tree.
If you have an App component that renders both Navbar and MainPage then you can move the router into that component:
export default class App extends Component {
render() {
return (
<BrowserRouter>
<div className="AppContainer">
<Navbar />
<MainPage />
</div>
</BrowserRouter>
);
}
}