0
votes

I am trying to add 'active' as className to my each in sidebar component. What I want is that whichever gets activated, it should attach class 'active' to it and then set CSS accordingly. I tried using react-router location props referring to this SO answer: https://stackoverflow.com/a/42766792/11349591, but unable to follow the syntax/result properly.

Here is my code for Sidebar.js

import React, {Component} from 'react'
import { NavLink, Link } from 'react-router-dom'
import '../../css/active.css';


export default function SideBar(){
    const { location } = this.props;

    const dashboardClass = location.pathname === "/" ? "active" : "";
    const userClass = location.pathname.match(/^\/user/) ? "active" : "";
    const listClass = location.pathname.match(/^\/list/) ? "active" : "";
        return (
            <div style={{flexBasis: '200px', backgroundColor: 'gray'}}>
                <nav style={{textAlign:'left'}}>
                    <ul className="side-bar">
                        <li className={dashboardClass}>
                            <i class="fa fa-pie-chart fa-2x" aria-hidden="true" style={{color:'#ccc'}}></i>
                            <Link to="/dashboard">
                                Dashboard
                            </Link>
                        </li>
                        <li className={userClass}>
                            <i class="fa fa-user-circle fa-2x" aria-hidden="true" style={{color:'#ccc'}}></i>
                            <Link to="/user" >User</Link>
                        </li>
                        <li className={listClass}>
                            <i class="fa fa-list-alt fa-2x" aria-hidden="true" style={{color:'#ccc'}}></i>
                            <Link to="/list">Table List</Link>
                        </li>
                    </ul>
                </nav>
            </div>
        )
}

App.js (Home component render Sidebar and Dashboard component)

function App() {
  return (
    <div className="App">
      <Switch>
          <Route exact path="/" component={Home} />

          <Route path="/register" component={Register} />

          <Route path="/login" component={Login} />
      </Switch>
    </div>
  );
}

Home.js

export default class Home extends Component {
    render() {
        return (
            <div style={{display: 'flex', flexDirection: 'row'}}>
                <SideBar/>
                <Dashboard/>
            </div>
        )
    }
}

My console report this problem: TypeError: Cannot read property 'props' of undefined

2

2 Answers

0
votes

You are trying to access this.props from a functional component and that's only possible in class based components. Change your code to this:

export default function SideBar({ location }){
   // Rest of the code

You also need to pass the router props down from Home to Sidebar component:

export default class Home extends Component {
    render() {
        return (
            <div style={{display: 'flex', flexDirection: 'row'}}>
                <SideBar {...this.props}/> // Pass the props down
                <Dashboard/>
            </div>
        )
    }
}
0
votes

To activate the Nav link you should use NavLink instead of Link. NavLink has one property called activeClassName, you should apply that class to it. let say if you have class called active which you want to apply after clicking on that then you can do this.

<NavLink to="/user" activeClassName={classes.active}>
    <li className={dashboardClass}>
       <i class="fa fa-pie-chart fa-2x" aria-hidden="true" style={{color:'#ccc'}}></i>
    </li>
</NavLink>