Detect click outside React component

后端 未结 30 1544
日久生厌
日久生厌 2020-11-22 13:54

I\'m looking for a way to detect if a click event happened outside of a component, as described in this article. jQuery closest() is used to see if the target from a click e

30条回答
  •  Happy的楠姐
    2020-11-22 14:27

    In my DROPDOWN case the Ben Bud's solution worked well, but I had a separate toggle button with an onClick handler. So the outside clicking logic conflicted with the button onClick toggler. Here is how I solved it by passing the button's ref as well:

    import React, { useRef, useEffect, useState } from "react";
    
    /**
     * Hook that triggers onClose when clicked outside of ref and buttonRef elements
     */
    function useOutsideClicker(ref, buttonRef, onOutsideClick) {
      useEffect(() => {
    
        function handleClickOutside(event) {
          /* clicked on the element itself */
          if (ref.current && !ref.current.contains(event.target)) {
            return;
          }
    
          /* clicked on the toggle button */
          if (buttonRef.current && !buttonRef.current.contains(event.target)) {
            return;
          }
    
          /* If it's something else, trigger onClose */
          onOutsideClick();
        }
    
        // Bind the event listener
        document.addEventListener("mousedown", handleClickOutside);
        return () => {
          // Unbind the event listener on clean up
          document.removeEventListener("mousedown", handleClickOutside);
        };
      }, [ref]);
    }
    
    /**
     * Component that alerts if you click outside of it
     */
    export default function DropdownMenu(props) {
      const wrapperRef = useRef(null);
      const buttonRef = useRef(null);
      const [dropdownVisible, setDropdownVisible] = useState(false);
    
      useOutsideClicker(wrapperRef, buttonRef, closeDropdown);
    
      const toggleDropdown = () => setDropdownVisible(visible => !visible);
    
      const closeDropdown = () => setDropdownVisible(false);
    
      return (
        
    {dropdownVisible &&
    {props.children}
    }
    ); }

提交回复
热议问题