zinx
zinx

Reputation: 93

Add active class to li items in react

I know there is various solutions for this question already on SO.But I can't make it work.

const [isActive, setActive] = useState(false);

const toggleClass = () => {
  setActive(!isActive);
};



<ul>
  <li>className="nav-item "><a href="#!" 
                className={isActive ? 'm-active nav-link': "nav-link"} 
                onClick={toggleClass} 
                data-toggle="tab"
                id=1>POSTS</a>
  </li>
  <li>........className={isActive ? 'm-active nav-link': "nav-link"} 
     onClick={toggleClass}.............................</li>
  <li>........className={isActive ? 'm-active nav-link': "nav-link"} 
     onClick={toggleClass}.............................</li>
  <li>........className={isActive ? 'm-active nav-link': "nav-link"} 
     onClick={toggleClass}.............................</li>
</ul>

So,right now when I click any li item ,it selects and add other li items to m-active className What this looks like you can see here.enter image description here

This is happening because it doesn't know which li to select .so, I thought to add id=1 , id=2, id=3and id =4 in all li tags and then pass that value with fuction and only add m-active class only to that li tag which has same id but I don't know how can I target only that li which have same id passed by the function

 const toggleClass = (id) => {
    setActive(!isActive);
 };

 <li>className="nav-item "><a href="#!" 
                className={isActive ? 'm-active nav-link': "nav-link"} 
                onClick={() => toggleClass(1)} 
                data-toggle="tab"
                id=1>POSTS</a>

Please see if you can help me with this or if you have other idea to solve this problem

Upvotes: 5

Views: 20312

Answers (3)

Xenark
Xenark

Reputation: 11

I see you already got a solution. That's great. I will add this to the solutions already provided.

As you want the className "active" to be applied on the

  • element clicked, you would likely want the first item by default already selected or marked "active".

    You do this by just setting the initial state to 1:

    const [active, setActive] = React.useState(1);

    Upvotes: 0

  • Robert May
    Robert May

    Reputation: 819

    As each <li /> element seems to be similar, you might want to consider using .map to populate your <ul /> to simplify the process here. Something like the following:

    const links = ['link1', 'link2', 'link3'];
    const [active, setActive] = useState(null);
    
    <ul>
      {links.map((link) => (
        <li className="nav-item">
          <a 
            href={`#${link}`} 
            className={`nav-link ${active == link && 'm-active'}`}
            onClick={() => setActive(link)}
          >{link}</a>
        </li>
      ))}
    </ul>
    

    All this code does is map your list of links to a list of elements that will be rendered on the page, each one has its onClick handler setting the active state var to the corresponding value.

    You can set more properties about each link if you use an object as each element of the links list rather than a string; I just figured this would be the simplest way to implement the functionality you're looking for.

    Upvotes: 2

    Sarun UK
    Sarun UK

    Reputation: 6736

    You can track the active Li id and based on that add the active class.

    import React, { useState } from "react";
    import "./styles.css";
    
    export default function App() {
      const values = [
        { id: 1, text: "LI-1" },
        { id: 2, text: "LI-2" },
        { id: 3, text: "LI-3" },
        { id: 4, text: "LI-4" }
      ];
      const [activeId, setActiveId] = useState();
    
      return (
        <div className="App">
          <ul>
            {values.map((val) => (
              <li onClick={() => setActiveId(val.id)}>
                {val.text} -- {activeId === val.id ? "Active" : "Inactive"}
              </li>
            ))}
          </ul>
        </div>
      );
    }
    

    Working Demo - https://codesandbox.io/s/naughty-sinoussi-bmy4p?file=/src/App.js:0-543

    Upvotes: 10

    Related Questions