You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断React Router中路由或其子路由是否处于激活状态?

解决方案

方案一:复用NavLink的激活判断逻辑

NavLink本身已经内置了完整的激活判断(包括匹配子路由的情况),直接通过它的onChange事件获取激活状态即可,无需自己编写匹配逻辑:

import { ExpandMore } from '@mui/icons-material';
import { ButtonBase, IconButton } from '@mui/material';
import cx from 'classnames';
import { NavLink, To } from 'react-router-dom';
import { useState } from 'react';

interface NavButtonProps {
  name: string;
  to: To;
}

export function NavButton(props: NavButtonProps) {
  const [isActive, setIsActive] = useState(false);

  return (
    <ButtonBase component="div" className={cx({ active: isActive })}>
      <NavLink 
        to={props.to} 
        onChange={({ isActive: navLinkActive }) => setIsActive(navLinkActive)}
      >
        {props.name}
      </NavLink>
      <IconButton onClick={openMenuWithLinksToNestedRoutes}>
        <ExpandMore />
      </IconButton>
    </ButtonBase>
  );
}

这个方案最简便,完全复用React Router内置的激活规则,和NavLink自身的激活逻辑保持一致,不需要手动处理路径匹配。

方案二:使用useMatch匹配父路由及子路由

如果想通过useMatch实现,可以构造包含子路由的匹配模式,同时处理原路径本身的匹配:

import { ExpandMore } from '@mui/icons-material';
import { ButtonBase, IconButton } from '@mui/material';
import cx from 'classnames';
import { NavLink, To, useMatch, useResolvedPath } from 'react-router-dom';

interface NavButtonProps {
  name: string;
  to: To;
}

export function NavButton(props: NavButtonProps) {
  // 解析传入的路径,处理相对路径情况
  const resolvedPath = useResolvedPath(props.to);
  // 构造匹配模式:匹配当前路径及所有子路由
  const parentPattern = `${resolvedPath.pathname}/*`;
  
  // 同时匹配原路径和子路由路径
  const match = useMatch(resolvedPath.pathname) || useMatch(parentPattern);
  const active = Boolean(match);

  return (
    <ButtonBase component="div" className={cx({ active })}>
      <NavLink to={props.to}>
        {props.name}
      </NavLink>
      <IconButton onClick={openMenuWithLinksToNestedRoutes}>
        <ExpandMore />
      </IconButton>
    </ButtonBase>
  );
}
  • useResolvedPath用于将相对路径转为绝对路径,确保匹配逻辑在任何路由层级都生效。
  • ${path}/*模式会匹配该路径下的所有子路由,比如/admin/*会匹配/admin/users、/admin/users/123等。

关键说明

两种方案都能实现需求:当访问子路由时,父级的NavButton会被标记为激活状态。方案一更推荐,因为它直接复用了React Router经过验证的激活逻辑,避免自己编写匹配规则可能出现的错误。

内容的提问来源于stack exchange,提问作者Denis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:55:33