Home > Software design >  creating logic inside className / Active Class
creating logic inside className / Active Class

Time:04-04

In my "DropdownMenu" component, I have multiple <Link>'s, created by "mapping" MenuItemContentSchool. I want the one that is clicked, to have a different class/style after. I figured, this could be done by creating logic inside the <Link> className, that would match clicked <Link> router path - with e.target.href.

So - in handleClick - ive created a "state variable" ev (reflecting e.target.href), to check which <Link> path , would be included inside it , testing the outcome with console.log("yes/no"). But that led to unexpected results, with multiple yes and no's sometimes. How to explain this / do it corectly ?

DropdownMenu

import { MenuItemContentSchool } from "./sub-components/MenuItemContentSchool"
import { Link } from "react-router-dom";
import { useState } from "react";


const DropdownMenu2 = () => {

  const [click, setClick] = useState("");
  const [ev, setEv] = useState("");

  const handleClick = (e) => {
    // setClick("hide-menu");
    setEv(e.target.href);   
  }
    
  return (
    <div className={`dropdown-holder-us ${click}`}>
    {MenuItemContentSchool.map((item) => {
      return (
        < Link 
            to={item.link} 

                   //  inserting logic here ˬ
            className={"d-content-us "   ( ev.includes(item.link) ? console.log("yes") : console.log("no ")  ) } 
            onClick={handleClick}  
            key={item.title} 
        >
          {item.title}
        </Link>
      )
    } )}

</div>
  )
}
export default DropdownMenu2

MenuItemContentSchool

export const MenuItemContentSchool = [
    {
        title:"v align",
        link:"/verticalalign",
        comp:"VerticalAlign"
    },
    {
        title:"flexbox",
        link:"/flexbox",
        comp:"Flexbox"
    },
    {
        title:"grid",
        link:"/grid",
        comp:"Grid"
    },
    {
        title:"centre",
        link:"/centre",
        comp:"Centre"
    },
    {
        title:"rel / abs",
        link:"/relabs",
        comp:"RelAbs"
    },
    {
        title:"animation",
        link:"/animation",
        comp:"Animation"
    },
    {
        title:"chunks",
        link: "/chunks",
        comp: "Chunks"
    },
    {
        title:"JS",
        link:"/js",
        comp:"Js"
    },
]

CodePudding user response:

Just use activeClassName to do that logic for you.

return (
    <div className={`dropdown-holder-us ${click}`}>
    {MenuItemContentSchool.map((item) => {
      return (
        < NavLink 
            to={item.link}
            className={({ isActive }) =>
              `d-content-us ${isActive ? activeClassName : ''}`
            }
            activeClassName="is-active"
            key={item.title}
        >
          {item.title}
        </NavLink >
      )
    } )}

Now is-active class will be added to the active link according to the URL.

CodePudding user response:

From v6 onwards of react-router use navData.isActive to toggle style. Instead of <Link> use <NavLink>.

    <NavLink
        to={item.link} 
        className={(navData) => (navData.isActive ? "d-content-us active-style" : 'd-content-us')}
        onClick={handleClick}  
        key={item.title} 
    >
      {item.title}
    </NavLink>
  • Related