i am trying to create a simple react project. it has a navbar, sidebar and the main content area.
first a home component is displayed.
home.js
import { useState } from "react";
import Navbar from "../navbar/navbar";
import Sidebar from "../sidebar/sidebar";
import "./style.css";
import { useSelector, useDispatch } from 'react-redux'
function Home() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
<>
<Navbar />
<div className="home-box d-flex">
{sidebarOpen && <div className="p-2 flex-fill"><Sidebar /></div>}
</div>
</>
);
}
export default Home;
my navbar has a button which will change state sidebarOpen.
my sidebar looks like this->
sidebar.js
import "./style.css";
import { Link } from "react-router-dom";
function Sidebar() {
return (
<div className="divSidebar">
<ul>
<li>
<Link to="/chess">
<img className="sidebar-img" src="images/sidebar/chess.png"></img>
<span className="sidebar-text">Chess</span>
</Link>
</li>
<li>
<Link to="/volleyball">
<img
className="sidebar-img"
src="images/sidebar/volleyball.png"
></img>
<span className="sidebar-text">Volleyball</span>
</Link>
</li>
<li>
<Link to="/football">
<img
className="sidebar-img"
src="images/sidebar/football.png"
></img>
<span className="sidebar-text">Football</span>
</Link>
</li>
<li>
<Link to="/tabletennis">
<img
className="sidebar-img"
src="images/sidebar/table-tennis.png"
></img>
<span className="sidebar-text">TableTennis</span>
</Link>
</li>
<li>
<Link to="/rugby">
<img className="sidebar-img" src="images/sidebar/rugby.png"></img>
<span className="sidebar-text">Rugby</span>
</Link>
</li>
</ul>
</div>
);
}
export default Sidebar;
when i click on chess, the respective component should be loaded.
chess.js
function Chess() {
return (
<>
<h1>chess</h1>
</>
);
}
export default Chess;
but the problem is my sidebar disappears. i only want the main content area to be changed nothing else. can someone help? let me know if u want to some more code.
---------edit
i have added console.log in two places. one is in the navbar where the toggle method is defined and another is in redux store where toggle state is defined. both the places onclick is working. i am able to see message but the sidebar is not getting rendered.
---------edit 2
App.js
import "./App.css";
import Navbar from "./components/navbar/navbar";
import { Route, Routes } from "react-router-dom";
import Chess from "./components/chess/chess";
import Volleyball from "./components/volleyball/volleyball";
import Football from "./components/football/football";
import TableTennis from "./components/tabletennis/tabletennis";
import Rugby from "./components/rugby/rugby";
import Home from "./components/home/home";
function App() {
return (
<div className="App">
<Routes>
<Route exact path="/" element={<Home />} />
<Route
path="/chess"
element={
<>
<Navbar />
<Chess />
</>
}
/>
<Route
path="/volleyball"
element={
<>
<Navbar />
<Volleyball />
</>
}
/>
<Route
path="/tabletennis"
element={
<>
<Navbar />
<TableTennis />
</>
}
/>
<Route
path="/football"
element={
<>
<Navbar />
<Football />
</>
}
/>
<Route
path="/rugby"
element={
<>
<Navbar />
<Rugby />
</>
}
/>
</Routes>
</div>
);
}
export default App;
When you click on Chess you navigate to "/chess"
So if u can't see your Navbar there, is because you have to render it there too.
Or, render the Navbar outside de Routes from BrowsterRouter.
We need to see the components rendering on "/chess" and the react-router-dom config on app.js (or on the top lvl you declare it)
----- edit ------
Ok, look this:
function App() {
return (
<BrowserRouter>
<NavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/test" element={<Test />} />
</Routes>
</BrowserRouter>
);
}
If you refactor your brower like this is gona be more clean to understand the code and even easy to escale.
As u see, the navBar is outside the Routes, so its gona be visible in all routes.
then you can have this:
-> one path -> one element
your Links on navbar (or sidebar or whatelse) are gona work good.
i found a way. i rendered <Sidebar /> again in all my child components.
like this->
chess.js
function Chess() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
{sidebarOpen && (
<div className="p-2 flex-fill">
<Sidebar />
</div>
)}
)
}
this way when i click on button the state is updated and sidebar is rendered automatically.
I was pushing code into github when somehow my react router code stopped working. The components are not rendering yet the url is changing. Even when I replace with a basic html tag, nothing renders. I am really lost and could use some help.
Dashboard.jsx
import React from "react";
import Home from './Home/homeDashboard.jsx'
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Map from '#material-ui/icons/MapOutlined';
import Test from './MyPlan/Modules.jsx';
function Dashboard() {
const routes = [
{
path: "/home",
main: () => <Home />
},
{
path: "/myplan",
main: () => <Test />,
},
];
return (
<div style={{ backgroundColor: '#F5F5F5', height: '100vh' }}>
<Router>
<div style={{ display: 'flex' }}>
<nav className={classes.nav}>
<IconButton className={classes.navBtn} component={Link} to="/home" style={{ color: "rgb(255,255,255)" }} >
<Tooltip title="Home" className={classes.toolTip}>
<HomeIcon />
</Tooltip>
</IconButton>
<IconButton className={classes.navBtn} component={Link} to="/myplan" style={{ color: "rgb(255,255,255)" }}>
<Tooltip className={classes.toolTip} title="My Plan" >
<Map />
</Tooltip>
</IconButton>
</nav>
<div style={{ flex: 1 }}>
<Switch>
{routes.map((route, index) => (
<Route
key={index}
path={route.path}
children={<route.main />}
/>
))}
</Switch>
</div>
</div>
</Router>
</div>
);
}
export default Dashboard;
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'm having issues rendering my Portfolio & Resume components.
I think the issue may be react-router related.
Here is my appjs file:
import React from 'react';
import Profile from './components/Profile/Profile'
import Header from './components/Header/Header'
import Footer from './components/Footer/Footer'
import Portfolio from './pages/Portfolio/Portfolio'
import Resume from './pages/Resume/Resume'
import {
Button,
Form,
FormControl,
Nav,
NavLink,
NavDropdown,
} from 'react-bootstrap';
import { BrowserRouter as Router, Switch, Route, } from 'react-router-dom'
import './App.css';
function App() {
return (
<Container className={'top_60'}>
{/* *Container adds space on both edges or sides of the page* */}
{/* Profile.js line 36 */}
<Grid container spacing={7}>
<Grid item xs={12}
sm={12}
md={4}
lg={3}>
<Profile/>
</Grid>
<Grid item xs>
<Router>
<Header />
<Switch>
<Nav.Link as={NavLink} to="/" />
<Route path="/portfolio">
<Portfolio />
</Route>
<Route path="/">
<Resume />
</Route>
</Switch>
</Router>
<Footer />
</Grid>
</Grid>
</Container>
);
}
export default App;
Resume & Portfolio component code as of right now:
1.Resumejs
import React from 'react'
const Resume = () => {
return (
<div>
Resume Page
</div>
)
}
export default Resume
2.Portfoliojs
import React from 'react'
const Portfolio = () => {
return (
<div>
Portfolio Page
</div>
)
}
export default Portfolio
I'm not getting any errors but the Portfolio & Resume components are both not rendering on the page.
Any suggestions would be appreciated.
<Switch> renders the first child that matches the location, in your case <Nav.Link as={NavLink} to="/" /> is being rendered.
Placing the Nav AFTER the Routes, within the Switch,
<Route path="/portfolio">
<Portfolio />
</Route>
<Route path="/">
<Resume />
</Route>
<Nav.Link as={NavLink} to="/" />
within the appjs file , seems to solve this issue.
Im trying to achieve when a sidebar collapse the body will make space for the sidebar and when it uncollapse
This is what it looks like when the sidebar uncollapse
enter image description here
and this is what it looks like when the sidebar collapse
enter image description here
import React from 'react';
import SideNav, {
Toggle,
Nav,
NavItem,
NavIcon,
NavText,
} from '#trendmicro/react-sidenav';
import '#trendmicro/react-sidenav/dist/react-sidenav.css';
export const SideBar = () => {
return (
<>
<SideNav
onSelect={(selected) => {
// Add your code here
}}
>
<SideNav.Toggle />
<SideNav.Nav defaultSelected='home'>
<NavItem eventKey='home'>
<NavIcon>
<i className='fa fa-fw fa-home' style={{ fontSize: '1.75em' }} />
</NavIcon>
<NavText>Home</NavText>
</NavItem>
<NavItem eventKey='charts'>
<NavIcon>
<i
className='fa fa-fw fa-line-chart'
style={{ fontSize: '1.75em' }}
/>
</NavIcon>
<NavText>Charts</NavText>
<NavItem eventKey='charts/linechart'>
<NavText>Line Chart</NavText>
</NavItem>
<NavItem eventKey='charts/barchart'>
<NavText>Bar Chart</NavText>
</NavItem>
</NavItem>
</SideNav.Nav>
</SideNav>
</>
);
};
export default SideBar;
and this on App.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Nav from './components/NavBar';
import Home from './screens/Home';
import Login from './screens/Login';
import Register from './screens/Register';
import SideBar from './components/SideBar';
import { GlobalProvider } from './context/GlobalState';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
function App() {
return (
<GlobalProvider>
<Router>
<Nav />
<SideBar />
<Switch>
<Route path='/' component={Home} exact />
{/* <Route path='/login' component={Login} exact /> */}
<Route path='/login' component={Login} exact />
<Route path='/register' component={Register} exact />
</Switch>
</Router>
</GlobalProvider>
);
}
export default App;
I tried adding margin in the body but it dosent look nice when you uncollapse because theres still more space. Sorry if this is not right
I want something like this
enter image description here
I'm kinda new and would really appreciate if you could help me
Thanks in advance !!!
If you look at the Trend Micro demo page they do add margins on the content. That is one approach that is already recommended by the module. You can add some CSS transition property so that it is as smooth as the expanding/collapsing of the sidebar. Just add more margin if the sidebar is expanded. Utilize the onToggle event of the sidebar to set the state as needed.
App.js
const [sideNavExpanded, setSideNavExpanded] = React.useState(false);
const contentStyle = {
marginLeft: sideNavExpanded ? "250px" : "70px", // arbitrary values
transition: "margin 0.2s ease"
};
return (
<div>
<SideBar
setSideNavExpanded={setSideNavExpanded}
sideNavExpanded={sideNavExpanded}
/>
<div style={contentStyle}>Some Content</div>
</div>
)
Sidebar.js
export const SideBar = ({ sideNavExpanded, setSideNavExpanded }) => {
return (
<>
<SideNav
onToggle={() => {
setSideNavExpanded(!sideNavExpanded);
}}
>
...
CodeSandBox: https://codesandbox.io/s/so-trend-micro-sidebar-fjo9r?file=/src/App.js