kun*_*uan 7 javascript reactjs material-ui use-effect
我将 Material-UI ClickAwayListener 组件与使用反应路由器的现有代码一起使用。该按钮位于 的外部<ClickAwayListener> ... </ClickAwayListener>,因此我预计onClickAway在导航到其他路线之前会触发该按钮。但它没有
下面是我的代码的复制,在某种程度上证明了我的意思
function Component(){
const handleClickAway = () => {
// Do something here
}
return (
<>
<button>
<Link to="/other-route">Click here </Link>
</button>
// Some other element here
<ClickAwayListener onClickAway={handleClickAway}>
<div>
// Content
</div>
</ClickAwayListener>
</>
)
}Run Code Online (Sandbox Code Playgroud)
因此,如果我单击外部的任何位置并被<ClickAwayListener>触发<button>,handleClickAway但如果我单击包含<button>与其他路线类似的位置,则不会。
我尝试查看源代码,我相信ClickAwayListener这部分负责检测点击
React.useEffect(() => {
if (mouseEvent !== false) {
const mappedMouseEvent = mapEventPropToEvent(mouseEvent);
const doc = ownerDocument(nodeRef.current);
doc.addEventListener(mappedMouseEvent, handleClickAway);
return () => {
doc.removeEventListener(mappedMouseEvent, handleClickAway);
};
}
return undefined;
}, [handleClickAway, mouseEvent]);Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>Run Code Online (Sandbox Code Playgroud)
据我所知,这部分将首先在组件安装/重新渲染时添加一个事件侦听器来单击事件,并在组件卸载之前删除该侦听器(默认行为)useEffect()。但如果是这种情况,那么在组件被任何涉及在 区域之外单击的事件卸载之前ClickAwayListener,onClickAway应该触发侦听器,因为侦听器仍然附加到单击事件。
简而言之,这是我期望的行为:
单击按钮 -->onClickAway触发 --> 组件卸载 --> 转到新路由 --> useEffect() 运行的清理代码 --> 监听器被删除
但这是迄今为止发生的事情
单击按钮 --> 组件卸载 --> 转到新路由 --> useEffect() 运行的清理代码 --> 监听器被删除
有人可以帮我解释为什么会发生这种情况吗?
小智 9
在Tejogol 链接的问题中,评论者建议在组件上使用这些道具ClickAwayListener,因为它允许组件在链接开始之前捕获触摸事件。
<ClickAwayListener mouseEvent="onMouseDown" touchEvent="onTouchStart">
Run Code Online (Sandbox Code Playgroud)
我和你遇到了同样的问题,这对我有用!这也是侵入性最小的,因为我不想弄乱我的react-router-dom代码。
ClickAwayListener组件的工作原理是将事件侦听器附加到document,当鼠标事件触发时,onClickAway仅当鼠标事件不在元素内部时才会触发。
该Link组件react-router-dom本质上呈现如下所示的内容:
<a onClick={() => navigate()}>click</a>
Run Code Online (Sandbox Code Playgroud)
当您单击链接并调用 时navigate(),React 会卸载当前组件并在下一框架中安装下一个页面组件。但问题是,document处理程序仅在下一次重新渲染后进行处理,此时,事件处理程序自ClickAwayListener卸载以来已被删除,因此不会调用任何内容。
这个问题可以通过等到下一次重新渲染之后处理程序被document调用来解决。
<button
onClick={() => {
setTimeout(() => {
history.push("/2");
});
}}
>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5423 次 |
| 最近记录: |