I am trying to make the actively selected navbar element change the background color via react state. However it does not fully work. When I click on an element in my navbar, it briefly gets styled correctly, but after a moment is reverted and my homepage element in the navbar becomes styled once more.
I have my (simplified) navbar code below:
function Navbar(props) {
const [clickedNavbarItem, setClickedNavbarItem] = React.useState("/");
return (
<ul>
<li>
<a
onClick={() => setClickedNavbarItem("/")}
className={clickedNavbarItem === "/" && "active"}
href="/"
>Solve
</a>
</li>
<li>
<a
onClick={() => setClickedNavbarItem("/about")}
className={clickedNavbarItem === "/about" && "active"}
href="/about"
>About
</a>
</li>
</ul>
)
}
To my understanding: When the user clicks a given anchor tag, it should run the onClick handler, which will re-assign the state. The navbar should then re-render, and the classname for the appropriately clicked item should have the "active" class, which should change the styling.
Additionally, the href should redirect the page as such (this is my React router code):
function App() {
return (
<>
<Navbar />
<Routes>
<Route path="/" element={<Solve />} />
<Route path="/about" element={<About />} />
<Route path="/explain" element={<Explain />} />
</Routes>
</>
)
}
I believe there is some interaction where the Navbar is getting reset perhaps when the href is activated, but I'm not entirely sure. Any help is appreciated.
Related
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 am trying to figure out how to deal with this issue I am having with Material UI tabs. So I have a navbar with three different tabs. They all link to different url's but two of them are kind of similar in a way. Please see my code below:
<Tabs indicatorColor="primary" value={this.state.tabsValue} onChange={this.setTabsValue}>
<Tab className={classes.tab}
label="Main"
value="main"
component={Link}
to="/main"
classes={{ selected: classes.selectedTab, }} />
<Tab className={classes.tab}
label="Shoes"
value="shoes"
component={Link}
to="/sale/shoes"
classes={{ selected: classes.selectedTab, }} />
<Tab className={classes.tab}
label="Sale"
value="sale"
component={Link}
to="/sale"
classes={{ selected: classes.selectedTab }} />
</Tabs>
Here is where setTabsValue is handling change events:
setTabsValue = (obj, val) => {
this.setState({
tabsValue: val
});
};
And when there is a prop change, the setTabsValue is being set also here:
componentWillReceiveProps(nextProps) {
const newRoute = window.location.pathname.split('/')[2];
if (this.state.tabsValue !== newRoute) {
// update currentRoute for user ping
this.currentRoute = newRoute;
this.setState({
tabsValue: this.isMainRoute(newRoute)
});
}
As you may notice, the last two tabs have a common point where the word 'sale' is in the destination route. This caused an issue where if I were to try to visit shoes, the active tab underline would be under the sale tab. Im not sure what is causing the issue but my guess it has something to do with the routes being similar for the last two tabs.
Basically the only way where the active tab underline will show under 'Shoes' tab is when I am already on 'Sale' tab and I click 'Shoes'. After a prop update,(maybe after a few seconds) it will go back to the 'Sale' tab, which is weird.
Not sure what is going wrong here but any help is appreciate. Thanks!
Not sure if you are familiar, but React Router is a great solution for this that I use in all of my projects. https://v5.reactrouter.com/web/guides/quick-start
The following is an example of how you would go about making an application that would route you to components for each page.
export default function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/topics">
<Topics />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
I am new here but a long time reader of StackOverflow content!
I am new to React and have a simple question about Multi-Pages App.
I did start to work on a website for a friend, I started with a one-pager but finally I did realize that I will need more then only one page. I installed react-router-dom and tried to set it up, the website doesn't return any errors, but only the SideBarMenu component is showing up !
the content of Home is not showing on / , same for the rest on /audio, /video, /images... And the weirdest part of it, if I write as URL for example some random thing like /asiomaos9j, it still show a blank website with the SideBarMenu without even crashing...
Anyone know why all my component on Home are not showing? Or even on /images the js file only contains a div with a H1 inside and this H1 not showing either... I can't figure out what I am doing wrong with this !
I did import as follow:
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
Then here is my App.js :
export default function App() {
return (
<React.StrictMode>
<Routes />
</React.StrictMode>
);
}
My Routes.js :
export default function Routes() {
return (
<Router>
<Switch>
<Route exact path='/' component={Home}></Route>
<Route exact path="/audio" component={AudioPlayerApp}></Route>
<Route exact path="/video" component={VideoPlayerApp}></Route>
<Route exact path="/images" component={ImagesApp}></Route>
</Switch>
<SideBarMenu pageWrapId={"page-wrap"} outerContainerId={"app"} />
</Router>
);
}
Finally as example, here is my Home.js
function Home(){
return(
<React.Fragment>
<Header />
<Services />
<ServicesContent />
<Media />
<MediaContent />
<Studio />
<StudioContent />
<Partenaires />
<PartenairesContent />
<Contact />
<ContactContent />
<Footer />
</React.Fragment>
)
}
export default Home;
Here as asked, SideBarMenu.js :
import React from 'react';
import { slide as Menu } from 'react-burger-menu';
import './components_css/SideBarMenu.css';
export default props =>{
return(
<Menu {...props}>
<a className="menu-item" href="#">
<span>+</span>Accueil
</a>
<a className="menu-item" href="#services_link">
<span>+</span>Services
</a>
<a className="menu-item" href="#media_link">
<span>+</span>Médias
</a>
<a className="menu-item" href="#studio_link">
<span>+</span>Studio
</a>
<a className="menu-item" href="#contact_link">
<span>+</span>Contact
</a>
</Menu>
);
};
These are links inside the Home page for the moment.
Take the exact out of the home route and place it at the end of all others
I have route.js component, in which I Import navbar.js component & homePage.js component. When I click on navbar menu , I want to go to specific section of homePage.js component.
Example, when I click on AboutMe menu then AboutMe section of homePage come. I try to follow
How to scroll to a specific targeted component when clicking on Navbar Link
this stack overflow link but it's not work, according to this answer when I wrap my link to ScrollLink, menu will not display.
Please help me I am new in reactjs.
render() {
if (this.state.redirect) {
return (
<Router>
<DIV className="template-nav">
<NavBar
menu={this.menu}
onClick={()=>this.changeRedirect()}
></NavBar>
</DIV>
<Redirect from="*" to="/" />
<Route
exact
path="/"
component={HomePage}
navBar_menu={this.navBar_menu}
/>
</Router>
);
}
return (
<Router>
<DIV className="template-nav">
<NavBar menu={this.menu}></NavBar>
</DIV>
</Router>
);
}
In my case, i have 6 menu in my application. In header part i have 'Next' and 'back' buttons. If i click next button, it should navigate to next menu, for back button, it should navigate to previous page. and header.js is a seperate component. Code is attached below
app.js
render() {
return (
<Router>
<div className="h-100">
<Header />
<ContentNavigation />
<Switch>
<Route exact path='/' component={WelcomeMenu} />
<Route path='/principal' component={PrincipleMenu} />
<Route path='/mycar' component={MycarMenu} />
<Route path='/abc' component={abcMenu} />
<Route path='/ijkmenu' component={ijkMenu} />
<Route path='/xyzmenu' component={xyzMenu} />
</Switch>
</div>
</Router>
);
}
header.js
render() {
return (
<div className="header-right text-right header-text-pd-tp">
<span>
<i className ="icon-arrow-left prev-next-icon prev-icon"></i>
BACK
</span>
Current Chapter
<span>
NEXT
<i className="icon-arrow-right prev-next-icon next-icon" aria-hidden="true"></i>
</span>
</div>
)
}
This is one way to do routing
this.props.history.push({
pathname: '/your_route_path'
})
Multiple ways- you can navigate to other component.
1-using Link
import {Link} from 'react-router-dom'
<Link to="/ijkmenu">
NEXT
<i className="icon-arrow-right prev-next-icon next-icon" aria-hidden="true"></i>
</Link>
2-using this.props.history.push()
<span onClick={()=> this.props.history.push('/ijkmenu')}>
NEXT
<i className="icon-arrow-right prev-next-icon next-icon" aria-hidden="true"></i>
</span>