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
相关产品推荐
相关产品推荐

