Varun Nair
Varun Nair

Reputation: 349

Adding a CSS class to a JSX in ReactJS

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.

Upvotes: 1

Views: 6051

Answers (4)

Amruth
Amruth

Reputation: 5912

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;

Upvotes: 1

Guillaume Kiz
Guillaume Kiz

Reputation: 443

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);

Upvotes: 1

Mayank Shukla
Mayank Shukla

Reputation: 104369

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

}

Upvotes: 3

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85545

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'
}

Upvotes: 1

Related Questions