首页 > 解决方案 > 如何通过 React 优化在不同菜单项之间切换 className?

问题描述

我有标题组件,我想在菜单的所有元素之间切换 className (如果菜单的一个元素处于活动状态并且用户正在单击另一个元素 - 该元素变为活动状态而所有其他元素都没有)。我有这样的代码

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>
  );
};

和样式来可视化切换类

  &-menu__link {
    color: lightgray;
  }

  .active {
    color: #fff;
  }

这种方法有效,但看起来令人毛骨悚然。也许有人知道如何优化它?

标签: javascriptjqueryreactjsmenuheader

解决方案


我不会使用索引,我会使用项目的文本。我还会在中包含该文本,href以便指示锚点导致的内容。为避免重复代码,您可以将菜单项放在可重用数组中,如下所示:

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>
    );
};

推荐阅读