📌  相关文章
📜  检测 React 组件外部的点击 (1)

📅  最后修改于: 2023-12-03 15:10:56.633000             🧑  作者: Mango

在 React 中检测组件外部的点击事件

在React中,我们可以使用事件冒泡机制从子组件中捕获外部事件。但是,当我们想要检测组件外部的点击事件时,该怎么办呢?本文将介绍三种方法来实现这一目的。

1. 通过 useRef 和 useEffect 钩子

这种方法使用 useRef 和 useEffect 钩子来检测组件外部的点击事件。首先,我们将 useRef 钩子用于保存一个指向组件的 DOM 节点的引用。然后,我们使用 useEffect 钩子来注册一个全局点击事件监听器。

import React, { useRef, useEffect } from 'react';

function OutsideClickDetector() {
  const ref = useRef(null);

  useEffect(() => {
    function handleClickOutside(event) {
      if (ref.current && !ref.current.contains(event.target)) {
        console.log('Clicked outside the component!')
      }
    }

    document.addEventListener("mousedown", handleClickOutside);
    
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [ref]);

  return <div ref={ref}>Component content</div>;
}

在上面的代码中,handleClickOutside 函数检测用户单击事件,并检查是否单击了组件外部。如果单击了组件外部,则会在控制台中打印出一条消息。

2. 使用 React Portal

React Portal 允许我们将组件渲染到 DOM 树的不同部分,因此我们可以在组件的父组件以外的某个地方创建一个隐形的 DOM 节点,并将组件渲染到该节点。随后,我们可以使用单击事件监听器来检测用户单击事件是否发生在该节点之外。下面是一个示例:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function Modal({ onClose }) {
  const [showCloseButton, setShowCloseButton] = useState(false);

  function handleClose() {
    setShowCloseButton(false);
    onClose();
  }

  return (
    <div>
      <div
        style={{position: "fixed", top: 0, bottom: 0, left: 0, right: 0}}
        onClick={() => setShowCloseButton(true)}
      />
      <div style={{position: "fixed", top: "50%", left: "50%"}}>
        Modal content
        {showCloseButton && <button onClick={handleClose}>Close modal</button>}
      </div>
    </div>
  )
}

function App() {
  const [showModal, setShowModal] = useState(false);

  function handleClickOutsideModal() {
    setShowModal(false);
  }

  return (
    <div>
      <button onClick={() => setShowModal(true)}>Show modal</button>
      {showModal && (
        ReactDOM.createPortal(
          <Modal onClose={() => setShowModal(false)} />,
          document.body
        )
      )}
      <div
        style={{position: "fixed", top: 0, bottom: 0, left: 0, right: 0}}
        onClick={handleClickOutsideModal}
      />
    </div>
  )
}

在上面的代码中,我们在页面中的隐形节点上注册了一个onClick事件监听器来关闭模态框。这意味着用户单击了模态框以外的任何位置时,我们都可以检测到并关闭它。

3.使用第三方库

最后,我们可以使用第三方库实现这一目的,例如 react-click-outside 和 react-onclickoutside。

  • react-click-outside
import React, { Component } from 'react';
import ReactClickOutside from 'react-click-outside';

class MyComponent extends Component {
  handleClickOutside() {
    console.log('Clicked outside the component!');
  }

  render() {
    return <div>Component content</div>;
  }
}

export default ReactClickOutside(MyComponent);
  • react-onclickoutside
import React, { Component } from 'react';
import onClickOutside from 'react-onclickoutside';

class MyComponent extends Component {
  handleClickOutside() {
    console.log('Clicked outside the component!');
  }

  render() {
    return <div>Component content</div>;
  }
}

export default onClickOutside(MyComponent);

以上是在React中检测组件外部的点击事件的三种方法,您可以根据自己的需要选择。希望这篇文章能对你有所帮助!