I have some code down and it works but my problem is that it changes all of the icons at the same time when i scroll over just one. I only want the icon that I hover over to change, so any help would be appreciated.
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {isHovered: false};
this.toggleHover = this.toggleHover.bind(this);
}
toggleHover() {
this.setState(prevState => ({isHovered: !prevState.isHovered}));
}
render() {
return (
<section className="info-section">
<div className="logo">
MATT
</div>
<div className="info-box">
<ul className="nav-links">
<li onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>
{this.state.isHovered
? <a className="home active" href="/">Home</a>
: <a className="home active" href="/"><FontAwesomeIcon icon={faHome} /></a>
}
</li>
<li onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>
{this.state.isHovered
? About
: <FontAwesomeIcon icon={faUser} />
}
</li>
Maybe you can try to use CSS.
<ul className="nav-links">
<li>
<a href="/">
<span>Home</span>
<FontAwesomeIcon icon={faHome} />
</a>
</li>
<li>
<a href="/about">
<span>Home</span>
<FontAwesomeIcon icon={faUser} />
</a>
</li>
...
a {
span {
display: none;
}
&:hover {
span {
display: block;
}
/* hide the icon base on their html tag or class */
i {
display: none;
}
}
}
If you really want to handle this through Javascript (which I'm not suggesting), you can try this.
class App extends Component {
state = {
hover: ""
};
handleMouseEnter = key => {
this.setState({ hover: key });
};
handleMouseLeave = () => {
this.setState({ hover: "" });
};
render() {
const { hover } = this.state;
return (
<ul>
<li
onMouseEnter={() => this.handleMouseEnter("home")}
onMouseLeave={this.handleMouseLeave}
>
<a href="/">
{hover === "home" ? <span>Hover Home</span> : <span>Home</span>}
</a>
</li>
<li
onMouseEnter={() => this.handleMouseEnter("about")}
onMouseLeave={this.handleMouseLeave}
>
<a href="/about">
{hover === "about" ? <span>Hover about</span> : <span>about</span>}
</a>
</li>
</ul>
);
}
}
Related
I am making an app in react. I am facing issue as my mobile menu remains open even after clicking the navbar items. Does anyone know how it can be closed upon clicking on the navbar items?
class Navbar extends Component {
state = { clicked: false};
handleClick = () => {
this.setState({clicked:!this.state.clicked})
};
render () {
return (
<nav className={"NavbarItems"}>
<h1 className={"navbar-logo"}>React<i className={"fab fa-react"}></i></h1>
<div className={"menu-icon"} onClick={this.handleClick}>
<i className={this.state.clicked ? 'fas fa-times': 'fas fa-bars'}></i>
</div>
<ul className={this.state.clicked?'nav-menu active':'nav-menu'}>
{MenuItems.map((item, index) => {
return (
<div key={index}>
<li >
<Link className={item.cName} to={item.url}>
{item.title}
</Link>
</li>
</div>
)
})}
</ul>
<Button><Link className={"nav-button"} to="/contact">Contact Us</Link></Button>
</nav>
)
}
}
export default Navbar;
Could be like this:
<Link to={() => {
this.handleClick();
return '/contact'
}} >Contact Us</Link>
I have a project that I am developing with React JS. The problem is that I have a button and when I click on it, I just want the icon on the button I click to change. But the icons on all the buttons I click change. My code is below.
constructor(props){
super(props)
this.state={
icon: false
}
}
active = (event) => {
this.setState({icon: !this.state.icon})
}
.....
const menu = ['A','B','C','A','B','C','A','B','C']
<div className="nav_menu">
<ul>
{menu.map((item,index) =>
<li key = {index}>
<Link data-id = {index} className="inactive" to={`${match.url}`} onClick={this.active}>
<span>
<span>
<FontAwesomeIcon icon={faHome} className="icon"/>
</span>
{item}
</span>
<FontAwesomeIcon data-id = {index} icon={icon ? faAngleDown:faAngleRight} className="angle"/>
</Link>
</li>
)}
</ul>
How do I fix this?
Having just one variable wouldn't suffice as you are not storing which button index has been clicked to accurately show the icon on only that button.
constructor(props){
super(props)
this.state={
icon: false,
clickedIndex: -1,
}
}
active = (clickedIndex)=> (event) => {
this.setState(prevState => ({icon: !prevState.icon, clickedIndex }));
}
.....
const menu = ['A','B','C','A','B','C','A','B','C']
<div className="nav_menu">
<ul>
{menu.map((item,index) =>
<li key = {index}>
<Link data-id = {index} className="inactive" to={`${match.url}`} onClick={this.active(index)}>
<span>
<span>
<FontAwesomeIcon icon={faHome} className="icon"/>
</span>
{item}
</span>
<FontAwesomeIcon data-id = {index} icon={(icon && index === this.state.clickedIndex) ? faAngleDown:faAngleRight} className="angle"/>
</Link>
</li>
)}
</ul>
Sample how you can select particular. live demo https://codesandbox.io/s/focused-browser-fls2w
export default class Abc extends Component {
constructor(props) {
super(props);
this.state = { icon: false };
}
active = item => {
this.setState({ icon: item });
};
render() {
const menu = ["A", "B", "C", "A", "B", "C", "A", "B", "C"];
return (
<div className="nav_menu">
<ul>
{menu.map((item, index) => (
<li
key={index}
onClick={() => this.active(index)}
style={{ color: this.state.icon === index ? "red" : "" }}
>
{item}
</li>
))}
</ul>
</div>
);
}
}
Problem:
I am creating a React web application. In there I have created a side navbar like this.
import React, { PureComponent } from "react";
import imagine from "../../../assets/img/sidebar-2.jpg";
class Sidebar extends PureComponent {
constructor(props) {
super(props);
this.state = {
width: window.innerWidth,
activeTabClassName: "tab1"
};
}
// activeRoute(routeName) {
// return this.props.location.pathname.indexOf(routeName) > -1 ? "active" : "";
// }
updateDimensions() {
this.setState({ width: window.innerWidth });
}
componentDidMount() {
this.updateDimensions();
window.addEventListener("resize", this.updateDimensions.bind(this));
}
render() {
const sidebarBackground = {
backgroundImage: "url(" + imagine + ")"
};
return (
<div className="sidebar" data-image={imagine} id="sidebar">
<div className="sidebar-background" style={sidebarBackground} />
<div className="sidebar-wrapper">
<div className="logo">
<a href="/" className="simple-text">
<img
src="../../images/favicon.png"
style={{ maxHeight: "50px" }}
/>
Trafficfine
</a>
</div>
<ul className="nav">
<li className="nav-item active">
<a className="nav-link" href="/admin/dashbord">
<i className="fas fa-tachometer-alt" />
<p>Dashboard</p>
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="/admin/officers">
<i className="fas fa-briefcase" />
<p>Officers</p>
</a>
</li>
<li>
<a className="nav-link" href="/admin/offences">
<i className="fas fa-times-circle" />
<p>Offences</p>
</a>
</li>
<li>
<a className="nav-link" href="/admin/drivers">
<i className="fas fa-bus-alt" />
<p>Drivers</p>
</a>
</li>
</ul>
</div>
</div>
);
}
}
export default Sidebar;
I want to change the active class dynamically when a user is clicking on the nav Item and add some styling to the active class. I saw some similar questions have been asked on the stack overflow and I tried those example. But through those, I was unable to achieve that. Can someone help me to solve my problem by modifying
my code? Thank you.
You already have your target class in state, you just need to add it like this
<div className={"sidebar " + this.state.activeTabClassName} data-image={imagine} id="sidebar">
And call this.setState( {activeTabClassName: "newActiveClass"} ) when you want to change it.
I wanted to add an 'active' class to a menu element, written in ReactJS. I tried doing it with the conventional JS method, but it failed. A click on any <li> tag, should result is removal of the 'active' class from all the <li>, and retain/ add it only to the one list tag in which the click was triggered.
Note: I know it may seem very naive on my part, but I'm just starting with ReactJS. Please ignore the stupidity.
import React, { Component } from 'react';
class Sidebar extends Component{
render(){
return(
<div className="sidebarContainer p-2">
<div className="mainMenu">
<ul className="levelOne pl-0">
<li className="mb-3 pl-2 menuTitle active" id="MenuTitle1">
...
</li>
<li className="mb-3 pl-2 menuTitle" id="MenuTitle2" onClick={this.clickMenu.bind(this,'MenuTitle2')}>
...
</li>
<li className="mb-3 pl-2 menuTitle" id="MenuTitle3" onClick={this.clickMenu.bind(this,'MenuTitle3')}>
...
</li>
</ul>
</div>
</div>
);
}
clickMenu(id){
// Add class 'active' on the clicked <li>, and remove from all other <li>
}
}
export default Sidebar;
I saw a similar question here, but that couldn't help me.
Idea is, store the id of clicked item in state variable and put the check with className. If item's id is same as state value then only assign the className active.
Write it like this:
class Sidebar extends Component{
constructor() {
super()
this.state = {
activeItem: 'MenuTitle1'
}
}
clickMenu(id){
// Add class 'active' on the clicked <li>, and remove from all other <li>
this.setState({
activeItem: id,
})
}
getClassName(id) {
if(id === this.state.activeItem) return 'mb-3 pl-2 menuTitle active'
return 'mb-3 pl-2 menuTitle'
}
render(){
return(
<div className="sidebarContainer p-2">
<div className="mainMenu">
<ul className="levelOne pl-0">
<li
id="MenuTitle1"
className={this.getClassName('MenuTitle1')}
onClick={this.clickMenu.bind(this,'MenuTitle1')}>
...
</li>
<li
id="MenuTitle2"
className={this.getClassName('MenuTitle2')}
onClick={this.clickMenu.bind(this,'MenuTitle2')}>
...
</li>
<li
id="MenuTitle3"
className={this.getClassName('MenuTitle3')}
onClick={this.clickMenu.bind(this,'MenuTitle3')}>
...
</li>
</ul>
</div>
</div>
);
}
}
You can maintain the state for clicked menu item:
clickMenu(id){
this.setState({activeMenu: id})
}
Then, define className like this:
className={
this.state.activeMenu == id {/* eg. "MenuTitle1" */}
? 'mb-3 pl-2 menuTitle active'
: 'mb-3 pl-2 menuTitle'
}
Like Bhojendra suggested store datas linked to your display inside your state then when you want to update the display of your component use the method setState, this will trigger render again (react style).
import React, { Component } from 'react';
import ReactDOM from "react-dom";
class Sidebar extends Component {
constructor() {
super();
this.state = {
activeMenuId: "MenuTitle1"
};
}
render() {
return (
<div className="sidebarContainer p-2">
<div className="mainMenu">
<ul className="levelOne pl-0">
<li className={`mb-3 pl-2 menuTitle ${this.state.activeMenuId === "MenuTitle1" ? "active" : ""}`} id="MenuTitle1" onClick={this.clickMenu.bind(this, 'MenuTitle1')}>
1
</li>
<li className={`mb-3 pl-2 menuTitle ${this.state.activeMenuId === "MenuTitle2" ? "active" : ""}`} id="MenuTitle2" onClick={this.clickMenu.bind(this, 'MenuTitle2')}>
2
</li>
<li className={`mb-3 pl-2 menuTitle ${this.state.activeMenuId === "MenuTitle3" ? "active" : ""}`} id="MenuTitle3" onClick={this.clickMenu.bind(this, 'MenuTitle3')}>
3
</li>
</ul>
</div>
</div>
);
}
clickMenu(id) {
// Add class 'active' on the clicked <li>, and remove from all other <li>
this.setState({activeMenuId: id});
}
}
export default Sidebar;
ReactDOM.render(<Sidebar />, document.body);
Another way of just make using initialstate and setState.
import React, { Component } from "react";
class Sidebar extends Component {
constructor(props) {
super(props);
this.initialState = {
MenuTitle1: "active",
MenuTitle2: "",
MenuTitle3: ""
};
this.state = this.initialState;
}
render() {
return (
<div className="sidebarContainer p-2">
<div className="mainMenu">
<ul className="levelOne pl-0">
<li
className={`mb-3 pl-2 menuTitle ${this.state.MenuTitle1} `}
id="MenuTitle1"
onClick={this.clickMenu.bind(this, "MenuTitle1")}
>
one
</li>
<li
className={`mb-3 pl-2 menuTitle ${this.state.MenuTitle2}`}
id="MenuTitle2"
onClick={this.clickMenu.bind(this, "MenuTitle2")}
>
two
</li>
<li
className={`mb-3 pl-2 menuTitle ${this.state.MenuTitle3}`}
id="MenuTitle3"
onClick={this.clickMenu.bind(this, "MenuTitle3")}
>
three
</li>
</ul>
</div>
</div>
);
}
clickMenu(id) {
this.setState(this.initialState);
this.setState({
[id]: "active"
});
}
}
export default Sidebar;
i am a new on React and i have a React component as in the next code and i cannot find a way to make the currentLanFlag img src to be dynamic and follow the user choose in the drop down languages menu ......
What i want is : when the user click on the anchor tag German, the img with CLass currentLanFlag to be a German Flag, same for English and the others Languages .
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { translate, Trans } from 'react-i18next';
import de from '../../../assets/img/de.png';
import en from '../../../assets/img/en.png';
import fr from '../../../assets/img/fr.png';
import pt from '../../../assets/img/pt.png';
import ar from '../../../assets/img/ar.GIF';
import '../../../assets/FontAwesome/css/font-awesome.min.css';
import './topNavComponenets.css';
const { version: appVersion } = require('../../../../package.json');
class TopNavComponenets extends Component {
constructor (props) {
super()
this.state = {
firstName: '',
lastName: ''
}
this.logout = this.logout.bind(this)
axios.get('api/auth/en/profile',{ withCredentials: true })
.then(response => this.setState({
firstName: response.data.firstName,
lastName: response.data.lastName,
}));
}
logout () {
axios.get('api/auth/en/logout',{ withCredentials: true })
}
render () {
const { i18n } = this.props;
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);;
};
let currentLanFlag = en;
return (
<div className="topNavComponenets">
<div className='infoContainer row'>
< div className="col-12 text-right">
<div className="userCont col-4">
<Link to="/user" ><i className="fa fa-user" title={"My Profile"}></i></Link>
<p className="infos">
{this.state.firstName} {this.state.lastName}
</p>
</div>
<div className='version col-4'>
<div className="dropdown show">
<a className="dropdown-toggle" href="" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img
className="currentLanFlag"
src={ currentLanFlag }
alt="Language Flag"/>
</a>
<div className="dropdown-menu" aria-labelledby="dropdownMenuLink">
<a onClick={() => changeLanguage('de')} className="dropdown-item"><img className="flag" src={de} alt=""/><Trans>German</Trans></a>
<a onClick={() => changeLanguage('en')} className="dropdown-item"><img className="flag" src={en} alt=""/><Trans>English</Trans></a>
<a onClick={() => changeLanguage('fr')} className="dropdown-item"><img className="flag" src={fr} alt=""/><Trans>French</Trans></a>
<a onClick={() => changeLanguage('pt')} className="dropdown-item"><img className="flag" src={pt} alt=""/><Trans>Portugues</Trans></a>
<a onClick={() => changeLanguage('ar')} className="dropdown-item"><img className="flag" src={ar} alt=""/><Trans>Arabic</Trans></a>
</div>
</div>
<p title={"CMS Version"}>v.{appVersion}</p>
</div>
<div className='buttonContainer col-4'>
<a href="/login"> <span onClick={this.logout}>
<i className="fa fa-power-off" title={"Logout"}></i>
</span></a>
</div>
</div>
</div>
</div>
)}}
export default translate('translations')(TopNavComponenets);
Personally, I would set currentLanFlag in your state.
this.state = {
...
currentLanFlag: 'en'
};
Then change your image tag to be something along the lines of
<img
className="currentLanFlag"
src={ this.state.currentLanFlag }
alt="Language Flag"/>
Your on click should then change the state of this.state.currentLanFlag.
Something along the lines of
// A function
changeLan = (event) {
this.setState({
currentLanFlag: event.target.data
});
changeLanguage(event.target.data);
}
// in your return
<a data='de' onClick={this.changeLan}><img className="flag" src={de} alt=""/><Trans>German</Trans></a>
this.setState will tell react "something changed, rerender" at that point your language flag will be updated to the new flag.
Please note, the above is not tested.
You can find nice documentation here
https://reactjs.org/docs/state-and-lifecycle.html
https://reactjs.org/docs/handling-events.html
Just you need make some minor changes. This is for if you need to switch between two different language.
import en from '../../../assets/img/en.png';
import de from '../../../assets/img/de.png';
1. set the current flag in your state
state = {
currLangFlag: 'en'
}
2. Replace your current event handler with this one
const changeLan = (lng) => {
this.setState({ currLangFlag: lng })
i18n.changeLanguage(lng)
}
3. Use the ternary operator you can switch the flag url after state update
{currLangFlag === 'en' ? <img src={en} alt={currLangFlag} /> : <img src={de} alt={currLangFlag} />}
4. Call the event handler
<NavLink onClick={() => changeLan('en')} to={this.props.location}>
<img className="flag" src={en} alt=""/><Trans>English</Trans>
</NavLink >
<NavLink onClick={() => changeLan('de')} to={this.props.location}>
<img className="flag" src={de} alt=""/><Trans>German</Trans>
</NavLink >