Next.js中如何对比当前pathname与路由实现导航项选中功能?
解决方案
基础场景(无动态路由,仅需前缀匹配)
你原来的exact: false配置只需要判断当前路径是否是目标路由的子路径,直接用简单的字符串匹配即可,代码如下:
import { useRouter } from 'next/router'; const NavBar = ({ item }) => { const { pathname } = useRouter(); // 根路径单独处理避免误匹配所有路由,同时增加后缀判断避免短路径前缀误匹配 const open = item.href === '/' ? pathname === '/' : pathname === item.href || pathname.startsWith(`${item.href}/`); // 后续逻辑和原来保持一致即可 ... }
复杂场景(包含动态路由匹配)
如果你的项目用到/posts/[id]这类Next.js动态路由,上面的字符串匹配无法生效,可以用下面的自定义匹配函数实现和react-router-dom的matchPath一致的效果:
import { useRouter } from 'next/router'; // 自定义路由匹配函数 // 参数说明:currentPath 当前路径,targetPath 目标匹配路径,exact 是否精确匹配 function matchPath(currentPath, targetPath, exact = false) { // 把Next.js动态路由占位符替换为正则匹配规则 const pattern = targetPath .replace(/\[.+?\]/g, '[^/]+') // 匹配/[param]格式的动态参数 .replace(/\/\*$/, '.*'); // 匹配通配符路由 // 生成对应正则 const matchRegex = exact ? new RegExp(`^${pattern}$`) : new RegExp(`^${pattern}(\\/|$)`); return matchRegex.test(currentPath); } const NavBar = ({ item }) => { const { pathname } = useRouter(); // 传入false对应你原来的非精确匹配需求 const open = matchPath(pathname, item.href, false); ... }
Next.js 13+ App Router 适配
如果你使用的是App Router,只需要把路由参数的获取方式换成usePathname即可,上面的匹配逻辑完全通用:
import { usePathname } from 'next/navigation'; const NavBar = ({ item }) => { const pathname = usePathname(); // 匹配逻辑和上面保持一致即可 const open = item.href === '/' ? pathname === '/' : pathname === item.href || pathname.startsWith(`${item.href}/`); ... }
注意:上述实现中获取的
pathname会自动忽略URL后缀的查询参数和哈希值,和原来react-router-dom的matchPath行为完全一致。
内容的提问来源于stack exchange,提问作者hotcakedev
相关产品推荐
相关产品推荐

