我有一个使用Reaction-Router创建的导航

Nav.tsx

import React from 'react'
import { menu } from './menu'
import { Link } from 'react-router-dom'
import styles from './HamburgerMenu.module.scss'

const HamburgerMenu: React.FC = () => {
  const [active, setActive] = React.useState<number>(0)
  console.log(active)

  return (
    <nav>
      <ul className={styles.menu}>
        {menu.map((item, index) => (
          <li
            onClick={() => setActive(index)}
            key={item.title}
            className={styles[active === index ? 'active' : '']}
          >
            <Link to={item.link}>{item.title}</Link>
          </li>
        ))}
      </ul>
    </nav>
  )
}

export default HamburgerMenu

菜单:

export const menu: IMenuItem[] = [
  {
    link: '/',
    title: 'главная'
  },
  {
    link: '/profile',
    title: 'профиль'
  },
  {
    link: '/discipline',
    title: 'наказания'
  },
  {
    link: '/store',
    title: 'магазин'
  },
  {
    link: '/statistics',
    title: 'статистика'
  }
]

Main.tsx:

import React from 'react'
import ReactDOM from 'react-dom/client'
import { RouterProvider, createBrowserRouter } from 'react-router-dom'
import Home from './pages/Home/Home'
import './assets/style/global.scss'
import NotFoundPage from './pages/NotFoundPage'
import Profile from './pages/Profile/Profile'

const router = createBrowserRouter([
  {
    element: <Home />,
    path: '/'
  },
  {
    element: <Profile />,
    path: '/profile'
  },
  {
    element: <NotFoundPage />,
    path: '*'
  }
])

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
)

Style.scss

.menu {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10;
    margin-right: 100px;

    li.nav-link-item {
        margin: 0px 50px;
        a {
            color: $white;
            opacity: 0.7;
            transition: opacity 0.3s ease;
            font-size: 20px;

            &:hover {
                opacity: 1;
            }
        }
    }

    li.nav-link-item:has(a.active) {
        border-radius: 10px;
        border: 5px solid #542c44;
        padding: 7px 42px;
    }
}

Layout.tsx-页面变成它

import React from 'react'
import { ILayoutProps } from './Laout.type'
import Header from '../Header/Header'
import Footer from '../Footer/Footer'
import styles from './Layout.module.scss'

const Layout: React.FC<ILayoutProps> = ({ children }) => {
    return (
        <div className={styles['layout']}>
            <Header />
            {children}
            <Footer />
        </div>
    )
}

export default Layout

当在'/''/profile'之间切换时,"active"类不断地被重置并切换到0,如果我想将"active"类添加到'/profile',那么我需要点击它2次,如果我在'/discipline','/store','/statistics'之间切换,类被正常分配.我理解这种行为很可能是因为'/discipline''/store''/statistics'没有声明页面,但是'/''/profile'又如何呢?为什么会发生这种情况,如何纠正这种情况?

推荐答案

使用NavLink组件,它默认为匹配的链接应用"active"类名,并使用CSS Select 具有当前匹配链接的li元素.

示例:

const HamburgerMenu: React.FC = () => {
  return (
    <nav>
      <ul className={styles.menu}>
        {menu.map((item, index) => (
          <li
            key={item.title}
            className="nav-link-item" // <-- something easily targetable
          >
            <NavLink end to={item.link}>
              {item.title}
            </NavLink>
          </li>
        ))}
      </ul>
    </nav>
  );
};
li.nav-link-item {
  /* li styling */
}

li.nav-link-item:has(a.active) {
  /* "active" li styling overrides */
}

资料:

演示

Edit how-to-set-active-class-in-react

enter image description here

由于您使用的是sass,因此这似乎是您正在使用的正确的css:

li.nav-link-item {
  margin: 0px 50px;

  a {
    color: #fff;
    opacity: 0.7;
    transition: opacity 0.3s ease;
    font-size: 20px;

    &:hover {
      opacity: 1;
    }
  }

  &:has(:global(a.active)) { // <-- access global non-SASS "active" class
    border-radius: 10px;
    border: 5px solid #542c44;
    padding: 7px 42px;
  }
}

enter image description here

Css相关问答推荐

视频覆盖不适用于reactjs样式的组件

如何在react 路由中设置活动类?

两列网格中左列第一个文本正下方的按钮

在 Shiny 中动态更改 bslib 值框的类

解释 "document.styleSheets[0].cssRules[0].style;"

创建一个CSS动画的对角线线条.

弹性布局溢出时的换行符

为什么左浮动上的清除:左也会影响右浮动,以及如何避免它

做一个像CodeSandbox的console那样的可拖拽的split panel

在revealjs/Quarto中定义一类反背景的幻灯片

内部和外部 div 之间的像素大小的间隙

tailwind 类的别名?

Adobe Illustrator 删除我在 svg 图像上的类名.我怎样才能防止这种情况?

如何断言 CSS 属性包含Cypress 测试中的一些文本?

CSS 使文本扩展并保持居中与圆形扩展 div 的问题

使用 CSS/HTML 更改悬停图像

如何在 Flexbox 中禁用等高列?

打印html时在页面上打印页码

CSS 中的星号属性是什么意思?

将样式应用于第一行的单元格