Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useClickAway判断不对 #1641

Closed
cl1107 opened this issue May 27, 2022 · 8 comments
Closed

useClickAway判断不对 #1641

cl1107 opened this issue May 27, 2022 · 8 comments
Assignees

Comments

@hchlq hchlq added bug Something isn't working and removed bug Something isn't working labels May 28, 2022
@hchlq
Copy link
Collaborator

hchlq commented May 28, 2022

感谢你的反馈,排查的情况是这样的:

  1. 我们默认是监听 document 上的 click 事件,因为阻止了冒泡,所以导致没有触发 clickAway 回调函数
  2. react-use 默认是监听 document 上的 mousedowntouchstart 事件,所以阻止冒泡也不会影响 clickAway 回调函数的触发

@hchlq
Copy link
Collaborator

hchlq commented May 28, 2022

我们可能需要讨论下是否要针对这一情况处理呢 @brickspert @crazylxr
我的想法是这样的:

  1. 因为我们需要监听顶层元素通过事件委托的方式看是否点击了目标元素之外,从而调用回调函数,在这一情况下阻止了冒泡,不触发回调感觉也有点合理
  2. 如果采用 mousedown 或者 touchstart 事件,我们就能兼容开发者在 click 下阻止冒泡,因为大多数情况下用 click 多于 mousedown 或者 touchstart 事件

各有一些优点和缺点,需要讨论看一下哈

@cl1107 欢迎提出你的想法💡

@hchlq
Copy link
Collaborator

hchlq commented May 28, 2022

上面的情况是在 react17 之后的,react17 之后,事件默认绑定在了根元素 #root 上,所以阻止冒泡直接不触发 document 上的 click 事件。

在 react17 以前,react 默认绑定事件在 document 上,即使阻止了冒泡也还是会触发 document 上的 click 事件。
在这个例子中,所以无论怎么点击 CodeSandbox文字 都不会显示 foobar。因为点击触发更新,重新渲染,visible 变为 true,此时调用 clickAway 回调函数,始终获取到最新的 visible ,即为 true,又将 visible 变为 false。

这个情况下我认为 ahooks 是合理的,因为 CodeSandbox文字 是在 foobar 之外的,也触发了 clickAway 事件,visible 变为 false 也是合情理的

可以这两个例子:
react16.8.6
react18.0.0

@cl1107
Copy link
Author

cl1107 commented May 28, 2022

最终我的建议是: 更改默认事件 clickmousedowntouchstart

我感觉改成mousedown和touchstart的效果更符合预期,点击第二个CodeSandbox文字,对于第一个CodeSandbox而言就是clickAway了,应该是要触发第一个的clickAway的回调函数的

@hchlq
Copy link
Collaborator

hchlq commented May 28, 2022

是的,不过默认如果改成了 mousedown 的话,有一个缺点就是在 mousedown 阻止冒泡的话和现在的 click 一样有问题的,只是说 mousedown 可能用的稍微少一点,所以默认事件建议改成 mousedown

@14glwu
Copy link

14glwu commented Jun 22, 2022

遇到类似问题,useClickAway 绑定的元素(假设为Parent)中的子元素(假设为Child1)如果销毁了,并且产生了其他的子元素(假设为Child2),点击Child2也会触发useClickAway。
导致现在只能修改监听事件或者阻止子元素冒泡

@mrcaidev
Copy link

mrcaidev commented Oct 7, 2022

遇到类似问题。

如果在 Modal 上使用 useClickAway 的话:

  • 监听 click 导致 Modal 根本打不开。(打开那一下点击也被算作了 "clickAway",于是 Modal 马上被关闭)
  • 监听 mousedown 则一切正常。

复现链接:useClickAway for modals

@liuyib liuyib self-assigned this Feb 23, 2023
@liuyib liuyib added this to To do in ahooks tasks via automation Feb 23, 2023
@liuyib
Copy link
Collaborator

liuyib commented Apr 23, 2024

楼主的使用方式,违背了 useClickAway 的设计用途:“监听目标元素外的点击事件”。

请考虑把不想触发 useClickAway 的元素放在 ref 引用的 dom 范围里(可以解决楼主在线 demo 里的问题):

+ <div ref={ref1} style={{ height: 100 }}>
      <div
        onClick={(e) => {
          e.stopPropagation();
          console.log("CodeSandbox");
          setVisible(true);
        }}
      >
        CodeSandbox
      </div>
-      <div ref={ref1} style={{ display: visible ? "block" : "none" }}>
+     <div style={{ display: visible ? "block" : "none" }}>
        foobar
      </div>
    </div>

@liuyib liuyib closed this as completed Apr 23, 2024
@liuyib liuyib removed the question label Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

No branches or pull requests

5 participants