如何在Next.js中结合MUI AppBar Tabs使用Link组件并保留激活效果
问题原因
你用Link包裹Tab之后,Tabs组件的直接子元素变成了Link而非Tab,MUI的Tabs依赖直接子Tab节点匹配激活状态,因此指示器、激活样式全部失效。
解决方案
不要用Link包裹Tab,直接利用MUI组件的component属性,将Tab的根渲染元素指定为Next.js的Link,同时配合Next.js的路由能力动态计算激活Tab,避免刷新页面后激活态错位。
完整实现代码
import AppBar from '@mui/material/AppBar'; import Tab from '@mui/material/Tab'; import Tabs from '@mui/material/Tabs'; import Link from 'next/link'; // Next.js Pages Router 导入下面的路由hook import { useRouter } from 'next/router'; // 如果是Next.js 13+ App Router,替换为下面的导入 // import { usePathname } from 'next/navigation'; const Navbar = () => { // Pages Router 计算激活Tab逻辑 const router = useRouter(); const selectedTab = router.pathname === '/album' ? 0 : router.pathname === '/profile' ? 1 : 0; // App Router 计算激活Tab逻辑 // const pathname = usePathname(); // const selectedTab = pathname === '/album' ? 0 : pathname === '/profile' ? 1 : 0; const handleTabChange = (event, newValue) => { // 无需额外处理路由跳转,Tab本身已经是Link组件,会自动处理跳转逻辑 }; return ( <AppBar position="static"> <Tabs value={selectedTab} onChange={handleTabChange} indicatorColor="secondary"> <Tab label="Album" component={Link} href="/album" /> <Tab label="Profile" component={Link} href="/profile" /> </Tabs> </AppBar> ) } export default Navbar;
补充说明
- 这种写法下
Tab本身就具备Next.jsLink的路由能力,同时Tabs的直接子元素还是Tab,可以正常识别激活状态,下划线指示器、激活样式都会正常生效 - 用路由路径计算激活态而不是硬编码useState初始值,可以解决刷新页面后激活态和实际路由不匹配的问题
- 如果有嵌套路由需要匹配,可以调整
selectedTab的判断逻辑,比如用pathname.startsWith('/album')来匹配所有/album开头的路径
内容的提问来源于stack exchange,提问作者Guillermo Brachetta
相关产品推荐
相关产品推荐

