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

react-aria useHover结合Tooltip组件时无法检测鼠标移出问题咨询

问题修复:React Aria Tooltip显示时useHover无法检测鼠标移出

问题概述

使用react-aria-components的Tooltip组件配合react-aria的useHover Hook时,触发Tooltip后从顶部方向移出目标元素,useHover无法检测到鼠标移出事件,导致目标元素始终保持悬停状态(比如蓝色背景);未触发Tooltip或从底部移出时则正常。

问题原因

Tooltip显示时默认会在目标元素上方渲染(默认定位逻辑),此时Tooltip的DOM元素会覆盖在目标元素顶部区域。由于Tooltip默认接收鼠标事件(pointer-events: auto),当鼠标从顶部移出目标元素时,实际是先进入Tooltip元素,导致目标元素的mouseleave事件无法触发,useHover因此无法感知到鼠标已离开。

修复方案

方案1:禁用Tooltip的鼠标事件(最简单)

给Tooltip添加pointer-events: none样式,让Tooltip不拦截鼠标事件,这样鼠标移出目标元素时,能直接触发mouseleave:

import { Tooltip } from 'react-aria-components';
import { useHover } from 'react-aria';

function App() {
  const { ref, isHovered } = useHover();

  return (
    <Tooltip 
      content="Tooltip"
      style={{ pointerEvents: 'none' }}
    >
      <div ref={ref} className={isHovered ? 'hovered' : ''}>
        Hover me
      </div>
    </Tooltip>
  );
}

方案2:改用HoverCard组件(更统一的状态管理)

React Aria的HoverCard组件本身集成了hover状态管理,同时可以实现Tooltip的功能,避免useHover与Tooltip的事件冲突:

import { HoverCard, HoverCardTrigger, HoverCardContent } from 'react-aria-components';

function App() {
  return (
    <HoverCard>
      <HoverCardTrigger asChild>
        {/* 直接通过HoverCard的上下文获取isHovered状态 */}
        <div className={({ isHovered }) => isHovered ? 'hovered' : ''}>
          Hover me
        </div>
      </HoverCardTrigger>
      <HoverCardContent>Tooltip</HoverCardContent>
    </HoverCard>
  );
}

方案3:手动同步Tooltip与Hover状态(自定义场景)

如果需要保留useHover的自定义逻辑,可以手动监听Tooltip的开关状态,同步更新hover状态:

import { useState } from 'react';
import { Tooltip } from 'react-aria-components';
import { useHover } from 'react-aria';

function App() {
  const [isHovered, setIsHovered] = useState(false);
  const [tooltipOpen, setTooltipOpen] = useState(false);
  const { ref } = useHover({
    onHoverChange: setIsHovered
  });

  return (
    <Tooltip
      content="Tooltip"
      isOpen={tooltipOpen}
      onOpenChange={(open) => {
        setTooltipOpen(open);
        // 当Tooltip关闭时,强制重置hover状态(此时鼠标已离开目标区域)
        if (!open) setIsHovered(false);
      }}
    >
      <div
        ref={ref}
        className={isHovered ? 'hovered' : ''}
        onMouseLeave={() => {
          setIsHovered(false);
          setTooltipOpen(false);
        }}
      >
        Hover me
      </div>
    </Tooltip>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:37:54