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

ClickAwayListener搭配Collapse或Fade过渡组件不生效该如何修复?

问题原因

你遇到的问题是点击事件冒泡冲突导致的:
你点击通知图标触发handleClick将showComponent设为true之后,这次点击事件会继续冒泡到全局document上,被ClickAwayListener的全局监听器捕获。因为你的通知图标不在ClickAwayListener包裹的DOM节点范围内,所以ClickAwayListener判定你点击了组件外部,直接执行onClickAway回调把showComponent又改回false,最终通知列表刚要渲染就被隐藏,看起来就像完全无法显示。

修复方案

推荐将通知图标和通知列表都放在同一个父容器内,再用ClickAwayListener包裹这个父容器,这样点击图标就属于点击ClickAwayListener内部元素,不会触发关闭逻辑,同时还可以给外层容器加定位样式,方便控制通知列表的弹出位置:

import Tooltip from "@material-ui/core/Tooltip";
import Fade from "@material-ui/core/Fade";
import React, { useState } from "react";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Icon from "@material-ui/core/Icon";

const HeaderAction = ({ icon, title, component }) => {
  const Component = component || (() => <div>NA</div>);

  const [showComponent, setShowComponent] = useState(false);

  const handleClick = () => {
    setShowComponent(!showComponent);
  };

  return (
    <ClickAwayListener onClickAway={() => setShowComponent(false)}>
      {/* 外层公共容器包裹图标和列表,相对定位用于控制弹出位置 */}
      <div style={{position: 'relative'}}>
        <Tooltip title={title || ""}>
          <div onClick={handleClick}>
            <Icon>{icon}</Icon>
          </div>
        </Tooltip>

        <Fade in={showComponent}>
          {/* 绝对定位让列表弹出在图标下方右侧,可根据需求调整 */}
          <div style={{position: 'absolute', right: 0, top: '100%', zIndex: 999}}>
            <Component />
          </div>
        </Fade>
      </div>
    </ClickAwayListener>
  );
};

export { HeaderAction };

如果不想调整DOM结构,也可以选择给图标的点击事件加阻止冒泡,避免事件传递到全局触发ClickAwayListener的回调:

<Tooltip title={title || ""}>
  <div onClick={(e) => {
    e.stopPropagation();
    handleClick();
  }}>
    <Icon>{icon}</Icon>
  </div>
</Tooltip>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:54:02