How can I put ternary for className active just single items of menu in react

Viewed 118

I'm new to reactjs. I used this syntax that puts class active just single items but it does not work, How I can use ternary that get class active just for Dashboard. Could you please help me? also, I would like to use the different icon of fontawsome for each item of the menu, how I should pass icon of fontawsome in menuItems.

const { Component } = React;

class Sidebar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      menuItems: [
        "Dashboard" ,
        "Customer",
        "Category",
        "Transaction",
        "Pick-up",
        "Stock",
        "Financial",
        "Report",
      ],
    };
  }
  render() {
    return (
      <div className="wrapper d-flex align-items-stretch">
        <nav id="sidebar">
          <div className="custom-menu">
            <button
              type="button"
              id="sidebarCollapse"
              className="btn btn-primary"
            >
              <i className="fa fa-bars"></i>
              <span className="sr-only">Toggle Menu</span>
            </button>
          </div>
          <div className="p-4">
            <h1>
              <a href="index.html" className="logo">
                Donyaro{" "}
              </a>
            </h1>
            <ul className="list-unstyled components mb-5">
            {this.state.menuItems&&this.state.menuItems.lenght?this.state.menuItems:[]}
           

              {this.state.menuItems.map((item) => (
                <li className={this.state.menuItems==="Dashboard" ? "active" :""} >
                  <a href={" "}>
                    <i className="fas fa-home mr-3"></i>
                    {item}
                  </a>
                </li>
               
              ))}
              
            </ul>
          </div>
          <div class="footer">
            <a href={" "}>

              <i className="fas fa-caret-down"></i>
            </a>
            <h6>
              <span>Welcome, </span>
              <a href="index.html" className="add-business">
                Add Business
              </a>
            </h6>
          </div>
        </nav>
      </div>
    );
  }
}

ReactDOM.render(<Sidebar />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

3 Answers

You can use clsx library and use it like this:

<ul className="list-unstyled components mb-5">
  {this.state.menuItems && this.state.menuItems.length ? this.state.menuItems : []}

  {this.state.menuItems.map(item => (
    <li
      className={clsx({
        active: item === 'Dashboard',
      })}
    >
      <a href="">
        <i className="fas fa-home mr-3"></i>
        {item}
      </a>
    </li>
  ))}
</ul>

Change your menu array from array of strings to array of objects so that you can provide a different icon for each menu. like this -

constructor(props) {
    super(props);
    this.state = {
      menuItems: [
        {
           item:"Dashboard",
           icon:"fa fa-dashboard"
        },
        {
           item:"Customer",
           icon:"fa fa-user"
        },
      ],
    };
  }

And change your map

{this.state.menuItems.map((menu) => (
   <li className={menu.item==="Dashboard" ? "active" :""} >
        <a href={" "}>
           <i className={`${menu.icon} mr-3`}></i>
           {menu.item}
         </a>
   </li>            
))}

Change your menuItems state's array of strings to an object array. icon in item array is the fa-{name of the icon} types, and href is the link of li which user should click to redirect.

this.state = {
      menuItems: [
        { name: "Dashboard", icon: "fa-tachometer", href: "" },
        { name: "Customer", icon: "fa-user-o", href: "" },
        { name: "Category", icon: "fa-object-group", href: "" },
        { name: "Transaction", icon: "fa-money", href: "" },
        { name: "Pick-up", icon: "fa-icon", href: "" },
        { name: "Stock", icon: "fa-icon", href: "" },
        { name: "Financial", icon: "fa-money", href: "" },
        { name: "Report", icon: "fa-print", href: "" }
      ]
    };

And create a function to render the menu items:

 renderItems = () => {
    if (
      this.state &&
      this.state.menuItems &&
      this.state.menuItems.concat.length > 0
    )
      return this.state.menuItems.map((item) => (
        <li className={item.name === "Dashboard" ? "active" : ""}>
          <a href={item.href}>
            {item.name}
            <i className={`"fa" ${item.icon}`}></i>
          </a>
        </li>
      ));
    return [];
  };

At the the end just call it in the render function:

 <ul className="list-unstyled components mb-5">
     {this.renderItems()}
 </ul>

Edit strange-hugle-d3qyj

Related