MUI MenuItem配置href后无法作为链接跳转的问题排查
问题描述
使用@mui/material ^5.10.8 + Next.js 13.2.4开发时,已通过全局配置将MuiButtonBase的LinkComponent替换为自定义LinkBehavior,但给MenuItem设置href="/"后无法实现页面跳转,DOM中渲染的是<li>标签而非预期的<a>标签。尝试直接给MenuItem指定LinkComponent或component属性时,还会出现TypeScript类型错误,最终排查出是同时在MenuItem上设置href和onClick属性导致的问题。
相关代码如下:
菜单组件代码
export const MenuComponent = () => { const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); const menuOpen = Boolean(anchorEl); return ( <Box> <IconButton onClick={(e) => setAnchorEl(e.currentTarget)}> <MenuIcon /> </IconButton> <Menu anchorEl={anchorEl} open={menuOpen} onClose={(e) => setAnchorEl(null)} > <MenuItem href="/">Inicio</MenuItem> </Menu> </Box> ); };
全局配置代码
import Link from "next/link"; const LinkBehavior = forwardRef(function LinkBehaviour( props: { href: URL; children: ReactNode }, ref: Ref<HTMLAnchorElement> | undefined ) { const { children, ...other } = props; return ( <Link ref={ref} {...other}> {children} </Link> ); }); const baseConfiguration = { components: { MuiLink: { defaultProps: { component: LinkBehavior, } as LinkProps, }, MuiButtonBase: { defaultProps: { LinkComponent: LinkBehavior, }, }, }, };
原因分析
MUI的MenuItem组件内部逻辑:当同时存在href和onClick属性时(包括Menu组件的onClose会间接绑定到MenuItem的点击事件),组件会优先以可点击列表项的形式渲染(<li>包裹按钮),而不会触发LinkComponent的渲染逻辑,因此无法生成带有跳转功能的<a>标签。
解决方案
方案1:移除不必要的onClick逻辑(优先推荐)
如果MenuItem不需要自定义点击逻辑,确保只设置href属性,此时MUI会自动使用全局配置的LinkComponent渲染为<a>标签,结合Next.js的Link实现跳转:
<MenuItem href="/">Inicio</MenuItem>
(注:Menu组件的onClose不会影响MenuItem的渲染类型,只要MenuItem本身没有额外绑定onClick即可)
方案2:保留点击逻辑并手动指定组件(适配TypeScript)
如果必须保留MenuItem的点击逻辑,需要手动指定component为自定义LinkBehavior,同时修正TypeScript类型错误:
- 调整LinkBehavior的props类型,适配MenuItem的传入参数:
import { ButtonBaseProps } from '@mui/material/ButtonBase'; import Link from "next/link"; const LinkBehavior = forwardRef<HTMLAnchorElement, ButtonBaseProps & { href: string }>( function LinkBehaviour(props, ref) { const { children, ...other } = props; return ( <Link ref={ref} href={other.href} {...other}> {children} </Link> ); } );
- 在MenuItem上指定component并绑定点击逻辑:
<MenuItem href="/" component={LinkBehavior} onClick={() => { setAnchorEl(null); // 其他自定义逻辑 }} > Inicio </MenuItem>
关键注意点
- 避免同时给MenuItem设置
href和未经过处理的onClick,否则会触发MUI的组件类型切换逻辑。 - 全局配置的
LinkComponent仅在组件以链接形式渲染时生效,若组件因点击逻辑切换为按钮/列表项,则该配置不生效。
内容的提问来源于stack exchange,提问作者techiejd
相关产品推荐
相关产品推荐

