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

MUI MenuItem配置href后无法作为链接跳转的问题排查

MUI MenuItem 配置 href 无法跳转(渲染为<li>而非<a>)的问题解决

问题描述

使用@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类型错误:

  1. 调整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>
    );
  }
);
  1. 在MenuItem上指定component并绑定点击逻辑:
<MenuItem 
  href="/"
  component={LinkBehavior}
  onClick={() => {
    setAnchorEl(null);
    // 其他自定义逻辑
  }}
>
  Inicio
</MenuItem>

关键注意点

  • 避免同时给MenuItem设置href和未经过处理的onClick,否则会触发MUI的组件类型切换逻辑。
  • 全局配置的LinkComponent仅在组件以链接形式渲染时生效,若组件因点击逻辑切换为按钮/列表项,则该配置不生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:02:14