Detect click outside React component

后端 未结 30 1191
日久生厌
日久生厌 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条回答
  •  无人及你
    2020-11-22 14:02

    I was stuck on the same issue. I am a bit late to the party here, but for me this is a really good solution. Hopefully it will be of help to someone else. You need to import findDOMNode from react-dom

    import ReactDOM from 'react-dom';
    // ... ✂
    
    componentDidMount() {
        document.addEventListener('click', this.handleClickOutside, true);
    }
    
    componentWillUnmount() {
        document.removeEventListener('click', this.handleClickOutside, true);
    }
    
    handleClickOutside = event => {
        const domNode = ReactDOM.findDOMNode(this);
    
        if (!domNode || !domNode.contains(event.target)) {
            this.setState({
                visible: false
            });
        }
    }
    

    React Hooks Approach (16.8 +)

    You can create a reusable hook called useComponentVisible.

    import { useState, useEffect, useRef } from 'react';
    
    export default function useComponentVisible(initialIsVisible) {
        const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
        const ref = useRef(null);
    
        const handleClickOutside = (event) => {
            if (ref.current && !ref.current.contains(event.target)) {
                setIsComponentVisible(false);
            }
        };
    
        useEffect(() => {
            document.addEventListener('click', handleClickOutside, true);
            return () => {
                document.removeEventListener('click', handleClickOutside, true);
            };
        });
    
        return { ref, isComponentVisible, setIsComponentVisible };
    }
    

    Then in the component you wish to add the functionality to do the following:

    const DropDown = () => {
        const { ref, isComponentVisible } = useComponentVisible(true);
        return (
           
    {isComponentVisible && (

    Dropdown Component

    )}
    ); }

    Find a codesandbox example here.

提交回复
热议问题