React Router v6 的 NavLink 缺少 isActive 属性

Mar*_*rek 5 reactjs react-router-dom

NavLink包的组件react-router-dom支持添加额外的逻辑来确定链接是否处于活动状态。至少旧版本支持这一点。以下是文档链接:https://reactrouter.com/web/api/NavLink/isactive-func

代码片段:

<NavLink
  to="/events/123"
  isActive={(match, location) => {
    if (!match) {
      return false;
    }

    // only consider an event active if its event id is an odd number
    const eventID = parseInt(match.params.eventID);
    return !isNaN(eventID) && eventID % 2 === 1;
  }}
>
  Event 123
</NavLink>
Run Code Online (Sandbox Code Playgroud)

版本 6 中似乎isActive不再支持属性。还有哪些其他选项可以实现相同的功能?

小智 8

NavLink activeClassName 属性不再存在。有了这个 prop,你可以为该特定 Link 传递一个类,并使用一些 CSS 进行修改,以显示它已变为活动状态,如下所示:

export function Header() {
  return (
    <header>
      <ul>
        <li>
          <NavLink activeClassName="active" to="/about" />
        </li>
        <li>
          <NavLink activeClassName="active" to="/profile" />
        </li>
      </ul>
    </header>
  )
}
Run Code Online (Sandbox Code Playgroud)

使用 V6,您必须手动执行此操作,并且可以通过将函数传递给 React 上的 className prop 来实现,如下所示:

export function Header() {
  return (
    <header>
      <ul>
        <li>
          <NavLink className={(navData) => navData.isActive ? "active" : "" } to="/about" />
        </li>
        <li>
          <NavLink className={(navData) => navData.isActive ? "active" : "" } to="/profile" />
        </li>
      </ul>
    </header>
  )
}
Run Code Online (Sandbox Code Playgroud)

  • 我不认为这是必要的。如果您阅读源代码 (/sf/answers/4785421511/),NavLink 会自动将“active”类添加到您在“className”中提供的任何内容之前。 (2认同)

Mar*_*rek 2

我制作了一个MenuLink组件,它包装Link并支持isActive这样输入的 props:

isActive?: (location: Location, path: Path) => boolean
Run Code Online (Sandbox Code Playgroud)

组件看起来像这样:

import React, { forwardRef } from 'react'
import { Link, NavLinkProps, useLocation, useResolvedPath } from 'react-router-dom'
import { Location, Path } from 'history'

type TMenuLinkProps = NavLinkProps & {
  isActive?: (location: Location, path: Path) => boolean
}

const MenuLink = forwardRef<HTMLAnchorElement, TMenuLinkProps>(({ to, isActive, className: classNameProp = '', ...rest }, ref) => {
  let location = useLocation()
  let path = useResolvedPath(to)

  let locationPathname = location.pathname
  let toPathname = path.pathname

  let isLinkActive = isActive ? isActive(location, path) : locationPathname.startsWith(toPathname)

  const className = [classNameProp, isLinkActive ? 'active' : null].filter(Boolean).join(' ')
  return <Link {...rest} ref={ref} className={className} to={to} />
})

export default MenuLink

Run Code Online (Sandbox Code Playgroud)