Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.js implement menu [highlight active link]

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 &#47;&#47;</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>
        )
    }
}
like image 220
B. Kwok Avatar asked Feb 17 '17 12:02

B. Kwok


People also ask

How do I make my nav link active react?

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.

How do you know which route is active in react?

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 .


2 Answers

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

like image 164
Yury Shapkarin Avatar answered Nov 11 '22 08:11

Yury Shapkarin


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>
    );    
  }
}
like image 16
Lyubomir Avatar answered Nov 11 '22 08:11

Lyubomir