The following React.js code renders a navbar with two links named 'about' and 'project'. On page load the 'about' link is active and colored red. When the other link is clicked the state of the navbar is set to 'project', 'about' link style is set back, and 'project' is colored red.
I achieve this by attaching a click handler to both link tags, and set the state of active to the name of the event.target.innerHTML.
I'm new to react, and I feel this is a really verbose way of going about this. I am aware that there is an activeClassName prop you can pass to a react-router link, but I want a way that does not use it.
import React, { Component } from 'react'
import { Link, Route } from 'react-router'
export default class Navbar extends Component {
constructor() {
super();
this.state = {
active: 'about'
}
this._handleClick = this._handleClick.bind(this);
}
_handleClick(e) {
this.setState({
active: e.target.innerHTML
});
}
render() {
let aboutStyle;
let projectStyle;
if (this.state.active === 'about') {
aboutStyle = { color: '#ff3333' };
projectStyle = {};
} else {
aboutStyle = {};
projectStyle = { color: '#ff3333' };
}
return (
<div className='navbar'>
<Link to='/'><h2>BK //</h2></Link>
<div className='menu'>
<Link style={aboutStyle} onClick={this._handleClick} to='about'>about</Link>
<Link style={projectStyle} onClick={this._handleClick} to='projects'>projects</Link>
</div>
</div>
)
}
}
The first method is to use the react-router-dom inbuilt method of NavLink instead of Link. The NavLink supports activeClassName which can help us assign active className to the link. Paste the below-updated code in your project Header. js file.
Use the useLocation() hook to get the current route with React Router, e.g. const location = useLocation() . The hook returns the current location object. For example, you can access the pathname as location. pathname .
At this day you can use NavLink from react-router-dom
. This object supports attributes as activeClassName
, activeStyle
, or isActive
(for functions).
import { NavLink } from 'react-router-dom';
<NavLink to='about' activeClassName="active">about</NavLink>
// Or specifing active style
<NavLink to='about' activeStyle={{color: "red"}}>about</NavLink>
// If you use deep routes and you need an exact match
<NavLink exact to='about/subpath' activeClassName="active">about</NavLink>
For more options read documentation: https://reacttraining.com/react-router/web/api/NavLink
maybe slightly less verbose... in Pseudocode
const menuItems = [
'projects',
'about',
];
class MenuExample extends React.Component {
_handleClick(menuItem) {
this.setState({ active: menuItem });
}
render () {
const activeStyle = { color: '#ff3333' };
return (
<div className='menu'>
{menuItems.map(menuItem =>
<Link
style={this.state.active === menuItem ? activeStyle : {}}
onClick={this._handleClick.bind(this, menuItem)}
>
{menuItem}
</Link>
)}
</div>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With