skip to Main Content

I have a quiestion for everyone here.
I am using react to make a portfolio page, and I am curious about one thing.
I just want to add a class to anchor tag when the tag is clicked, and i want to remove the class when the other anchor tag(of course this newly clicked one is gonna have the class) is clicked.
I just want to know about it and want to adopt it to improve my coding skills.
Hope lots of people here can help me.

The one below is my jsx code.

export function HeaderMenu() {
  const [menuList, setMenuList] = useState([]);
  useEffect(() => {
    fetch("data/menu.json")
      .then((res) => res.json())
      .then((result) => setMenuList(result))
      .catch((error) => console.log(error));
  }, []);

  return (
    <div>
      <nav>
        <ul className="header__menu">
          {menuList.map((menu, index) => (
            <li key={index}>
              <Menu href={menu.href} name={menu.name} />
            </li>
          ))}
        </ul>
      </nav>
      <button
        id="menu_toggle"
        className="header__toggle"
        aria-label="navigation menu toggle"
      >
        <i className="fa-solid fa-bars"></i>
      </button>
    </div>
  );
}

The one below is the component of the .

import React from "react";

export default function Menu({ href, name }) {
  return (
    <a className="header__menu__item" href={href}>
      {name}
    </a>
  );
}

I tried lots of things in Internet but i couldn’t find the right answer.
Thank you!

2

Answers


  1. I usually use some logic like using useState or useContext for multiple component

    import { Dispatch, SetStateAction, createContext, useState, useEffect, useContext } from "react";
    
    export const MenuContext = createContext<[string | null, state: Dispatch<SetStateAction<string | null>>]>([null, () => { }]);
    
    export function HeaderMenu() {
      const [menuList, setMenuList] = useState([]);
      const [selectedMenu, setSelectedMenu] = useState(null);
    
      useEffect(() => {
        fetch("data/menu.json")
          .then((res) => res.json())
          .then((result) => setMenuList(result))
          .catch((error) => console.log(error));
      }, []);
    
      return (
        <div>
          <nav>
            <ul className="header__menu">
              <MenuContext.Provider value={[selectedMenu, setSelectedMenu]}>
                {menuList.map((menu, index) => (
                  <li key={index}>
                    <Menu href={menu.href} name={menu.name} />
                  </li>
                ))}
              </MenuContext.Provider>
            </ul>
          </nav>
          <button
            id="menu_toggle"
            className="header__toggle"
            aria-label="navigation menu toggle"
          >
            <i className="fa-solid fa-bars"></i>
          </button>
        </div>
      );
    }
    
    import React from "react";
    import { MenuContext } from "path to MenuContext";
    
    export function Menu({ href, name }) {
      const [selectedMenu, setSelectedMenu] = React.useContext(MenuContext)
    
      return (
        <a onClick={() => setSelectedMenu(name)} className={`header__menu__item ${selectedMenu == name ? "your-class-here : null}`} href={href}>
          {name}
        </a>
      );
    }
    

    Hope this help :>

    Login or Signup to reply.
  2. You can manage the state of the active anchor tag within the HeaderMenu component.

    import React, { useState, useEffect } from "react";
    import Menu from "./Menu"; // Import the Menu component
    
    export function HeaderMenu() {
      // State to store the menu items and the index of the active menu item
      const [menuList, setMenuList] = useState([]);
      const [activeMenuIndex, setActiveMenuIndex] = useState(null);
    
      // Fetch menu data on component mount
      useEffect(() => {
        fetch("data/menu.json")
          .then((res) => res.json())
          .then((result) => setMenuList(result))
          .catch((error) => console.log(error));
      }, []);
    
      // Function to handle menu item click
      const handleMenuClick = (index) => {
        setActiveMenuIndex(index); // Set the active menu index
      };
    
      return (
        <div>
          <nav>
            <ul className="header__menu">
              {/* Map through menuList to render menu items */}
              {menuList.map((menu, index) => (
                <li key={index}>
                  {/* Render Menu component with props */}
                  <Menu
                    href={menu.href}
                    name={menu.name}
                    isActive={activeMenuIndex === index} // Pass isActive prop to indicate if menu is active
                    onClick={() => handleMenuClick(index)} // Pass onClick handler to handle menu click
                  />
                </li>
              ))}
            </ul>
          </nav>
          {/* Button element */}
          <button
            id="menu_toggle"
            className="header__toggle"
            aria-label="navigation menu toggle"
          >
            <i className="fa-solid fa-bars"></i>
          </button>
        </div>
      );
    }
    

    Then for the Menu Component:

    import React from "react";
    
    export default function Menu({ href, name, isActive, onClick }) {
      return (
        // Anchor tag with conditional class based on isActive prop
        <a
          className={`header__menu__item ${isActive ? "active" : ""}`}
          href={href}
          onClick={onClick} // Pass onClick handler to handle click event
        >
          {name}
        </a>
      );
    }
    
    1. activeMenuIndex state variable is used to keep track of the index of
      the currently active menu item.
    2. handleMenuClick function is called when a menu item is clicked,
      updating the activeMenuIndex state.
    3. In the Menu component, the isActive prop is used to conditionally
      apply the "active" class to the anchor tag.
    4. onClick event handler is passed down to the Menu component to handle
      the click event.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search