ReactJS 按钮点击事件冒泡问题及解决方案

在 ReactJS 中,如果有多个按钮都添加了 document.addEventListener('click', handleClickOutside) 事件监听器,例如:

function handleClickOutside(e) {
  if (!contentRef.current?.contains(e.target)) {
    setIsOpenContent(false);
  }
}

那么当点击按钮 A 展示下拉菜单时,点击按钮 B 并不会触发 A 的 handleClickOutside 事件。这是因为当按钮 B 被点击时,事件会冒泡到包含按钮的父元素上,而不是传递给 A 按钮所在的元素。因此,点击按钮 B 不会被视为点击在 A 按钮以外。

解决方案:

为了解决这个问题,可以在按钮 B 上添加一个单独的点击事件处理程序,以关闭 A 按钮的下拉菜单。可以使用 React 的 useState 钩子来管理两个按钮的状态。

function App() {
  const [isOpenA, setIsOpenA] = useState(false);
  const [isOpenB, setIsOpenB] = useState(false);

  const handleToggleA = () => {
    setIsOpenA(!isOpenA);
  };

  const handleToggleB = () => {
    setIsOpenB(!isOpenB);
    setIsOpenA(false); // 关闭 A 按钮的下拉菜单
  };

  const handleClickOutside = (e) => {
    if (!contentRef.current?.contains(e.target)) {
      setIsOpenA(false);
      setIsOpenB(false);
    }
  };

  useEffect(() => {
    document.addEventListener('click', handleClickOutside);
    return () => {
      document.removeEventListener('click', handleClickOutside);
    };
  }, []);

  return (
    <div>
      <button onClick={handleToggleA}>A</button>
      {isOpenA && (
        <div ref={contentRef}>
          {/* dropdown 内容 */}
        </div>
      )}

      <button onClick={handleToggleB}>B</button>
      {isOpenB && (
        <div ref={contentRef}>
          {/* dropdown 内容 */}
        </div>
      )}
    </div>
  );
}

这样,当点击按钮 A 展开下拉菜单时,点击按钮 B 会关闭 A 按钮的下拉菜单,并展示 B 按钮的下拉菜单。点击页面其他位置时,会关闭所有下拉菜单。


原文地址: https://www.cveoy.top/t/topic/qmRF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录