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

React钩子事件监听器内更新状态导致元素默认行为失效

问题原因与修复方案

你的问题出在当前钩子没有区分点击事件是发生在目标div内部还是外部,导致点击菜单内的按钮时也会触发onClickOutside,执行setIsMenuOpen(false)关闭菜单——菜单组件卸载/重新渲染的过程会中断按钮的默认滚动行为。

修复后的钩子代码

export function useClickOutside({
  ref,
  onClickOutside,
}: {
  ref: React.RefObject<HTMLElement>;
  onClickOutside: () => void;
}) {
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      // 仅当点击目标不在ref指向的元素内部时,才执行外部点击逻辑
      if (ref.current && !ref.current.contains(event.target as Node)) {
        onClickOutside();
      }
    }
    document.addEventListener("pointerdown", handleClickOutside);

    return () => {
      document.removeEventListener("pointerdown", handleClickOutside);
    };
  }, [ref, onClickOutside]); // 添加依赖数组,避免重复绑定事件
}

关键修复点

  1. 添加内部点击判断:通过ref.current.contains(event.target as Node)检查点击位置,只有外部点击才触发状态更新,菜单内的点击不会触发关闭逻辑,按钮的默认滚动行为可以正常完成。
  2. 补充useEffect依赖数组:避免组件每次渲染都重复绑定/解绑事件,优化性能的同时防止不必要的副作用触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:34:53