简体   繁体   中英

How to optimize toggling className between different menu items by React?

I have header component, where I want to toggle className between all the elements of menu (if one of the elements of menu is active and user is clicking to another element - this element become active and all others no). I have a code like this

import React, { useState } from 'react';
import './header.scss';

export const Header = ({ favoriteCount }) => {
  const [activeIndex, setActiveIndex] = useState(0);
  function toggleClass(index) {
    setActiveIndex(index);
  }

  return (
    <header className="header">
      <div className="container header-container">
        <ul className="header-menu">
          <li>
            <a
              className={
                activeIndex === 0
                  ? 'header-menu__link active'
                  : 'header-menu__link'
              }
              onClick={() => {
                toggleClass(0);
              }}
              href="##"
            >
              Characters
            </a>
          </li>
          <li>
            <a
              className={
                activeIndex === 1
                  ? 'header-menu__link active'
                  : 'header-menu__link'
              }
              onClick={() => {
                toggleClass(0);
              }}
              href="##"
            >
              Favorites
            </a>
          </li>
        </ul>
        <div className="header-favorite-count">
          <i className="far fa-heart"></i>
          {favoriteCount}
        </div>
      </div>
    </header>
  );
};

and styles to visualise toggling classes

  &-menu__link {
    color: lightgray;
  }

  .active {
    color: #fff;
  }

This approach is working but looks creepy. Maybe somebody knows how to optimize it?

I wouldn't use the index, I'd use the text of the item. I'd also include that text in the href so that there's an indication of what the anchor leads to. To avoid repeated code, you might put the menu items in a reusable array, something like this:

const menuItems = [
    "Characters",
    "Favorites",
];

export const Header = ({ favoriteCount }) => {
    const [activeItem, setActiveItem] = useState("");

    const setActiveItem = useCallback((event) => {
        setActiveItem(event.currentTarget.href.substring(2));
    }, []);

    const list = menuItems.map(item =>
        <li key={item}>
            <a
                className={`header-menu__link ${item === activeItem ? "active" : ""}`}
                onClick={setActiveItem}
                href={"##" + item}>
                {item}
            </a>
        </li>
    );
  
    return (
        <header className="header">
            <div className="container header-container">
                <ul className="header-menu">
                    {list}}
                </ul>
                <div className="header-favorite-count">
                    <i className="far fa-heart"></i>
                    {favoriteCount}
                </div>
            </div>
        </header>
    );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM