mistersholmes
mistersholmes

Reputation: 61

React js Active Menu Item with useState

I've been trying to add a menu with an active styling by using useState in React js but for some reasons it only stays in active state, does not go back to inactive when you click on the other menu item. On the other hand, it works perfectly when I pass down my active state as props from Sidebar.js

React version: "react": "^17.0.2" Node version: v16.0.0

Here is my code:

SideLink.js

import React, {useState} from "react";

const SideLink = ({ name, Icon}) => {
  const [active, setactive] = useState("Home")

  return (
    <li className="group" onClick={() => setactive(name)}>
      <a href={name.toLowerCase()} className="cursor-pointer block mb-2 pointer-events-none">
        <div className="inline-block">
          <div
            className={`
            flex items-center 
            group-hover:bg-blue-50 
            group-hover:text-red-500 
            rounded-full pl-2 py-3 pr-6
            ${active === name ? "text-red-400" : ""}
            `}
            >
            <Icon />
            <span className="ml-2 font-bold text-xl">{name}</span>
          </div>
        </div>
      </a>
    </li>
  );
};

export default SideLink;

Sidebar.js

import React, {useState} from "react";
import SideLink from "../../assets/components/SideLink";
import {
  BookmarksIcon,
  ExploreIcon,
  HomeIcon,
  ListsIcon,
  MessagesIcon,
  MoreIcon,
  NotificationsIcon,
  ProfileIcon,
} from "../../assets/icons/Icon";


const sideLinks = [
  {
    name: "Home",
    icon: HomeIcon,
  },
  {
    name: "Explore",
    icon: ExploreIcon,
  },
  {
    name: "Notifications",
    icon: NotificationsIcon,
  },
  {
    name: "Messages",
    icon: MessagesIcon,
  },
  {
    name: "Bookmarks",
    icon: BookmarksIcon,
  },
  {
    name: "Lists",
    icon: ListsIcon,
  },
  {
    name: "Profile",
    icon: ProfileIcon,
  },
  {
    name: "More",
    icon: MoreIcon,
  },
];

const Sidebar = () => {

  return (
    <div className="w-72 flex flex-col justify-between px-2">
      <div>
        <nav>
          <ul>
            {sideLinks.map(({ name, icon }) => (
              <SideLink key={name} name={name} Icon={icon}/>
            ))}
          </ul>
        </nav>
      </div>
      <div>bottom</div>
    </div>
  );
};

export default Sidebar;

Thank you!

Upvotes: 1

Views: 2062

Answers (1)

Federkun
Federkun

Reputation: 36999

Keep in mind that in your example each SideLink maintain their own independent state. When one of those call its own setactive, it doesn't have any effect on any other.

What I think you really want is one piece of state that live in a central location, the parent component, Sidebar, and forward to SideLink that value and the means to change that it.

Upvotes: 3

Related Questions