Material UI:React.forwardRef封装的首个MenuItem不显示Tooltip问题
我基于Material-UI的<MenuItem />组件,通过React.forwardRef封装了一个通用自定义组件,在<Menu />组件中多次使用,有时传递ref、有时不传递。给该组件添加<Tooltip />后发现:菜单中第一个组件实例的Tooltip无法显示,其他实例则完全正常。
移除<MenuItem />上的innerRef={ref}属性就能解决问题,但我不清楚背后的原因。我知道可以用<span />包裹<MenuItem />来规避这个问题,但希望搞懂具体原理和Tooltip失效的根源。
问题根源:Menu的焦点管理与ref绑定冲突
Material-UI的<Menu />组件有内置的焦点逻辑:渲染完成后会自动将焦点设置到第一个菜单项的DOM节点上。而你通过React.forwardRef把外部传入的ref直接绑定到第一个<MenuItem />的innerRef时,会触发以下冲突:
- Tooltip的显示依赖监听目标元素的
mouseenter、focus等事件 - 第一个MenuItem被Menu自动设置焦点后,其DOM节点的事件上下文被Menu的焦点管理逻辑抢占,导致Tooltip无法正常捕获触发事件
- 后续的MenuItem不会被Menu自动设置焦点,ref绑定不会干扰Tooltip的事件监听流程,因此能正常显示Tooltip
两种解决方案的原理
- 移除
innerRef={ref}:此时MenuItem的DOM节点不会被外部ref(包括Menu的焦点逻辑)直接持有,Tooltip的事件监听可以正常绑定到元素上,不受焦点管理逻辑的干扰。 - 用
<span />包裹<MenuItem />:span会成为Tooltip的直接目标元素,Tooltip的事件监听绑定在span节点上,而非被Menu焦点逻辑影响的MenuItem节点,因此能正常触发显示。
内容的提问来源于stack exchange,提问作者Michael Sims
相关产品推荐
相关产品推荐

