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> ) } }
Advertisement
Answer
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> ); } }