Detect click outside React component

后端 未结 30 1224
日久生厌
日久生厌 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:12

    Refs usage in React 16.3+ changed.

    The following solution uses ES6 and follows best practices for binding as well as setting the ref through a method.

    To see it in action:

    • Class Implementation
    • Hooks Implementation

    Class Implementation:

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    /**
     * Component that alerts if you click outside of it
     */
    export default class OutsideAlerter extends Component {
        constructor(props) {
            super(props);
    
            this.wrapperRef = React.createRef();
            this.setWrapperRef = this.setWrapperRef.bind(this);
            this.handleClickOutside = this.handleClickOutside.bind(this);
        }
    
        componentDidMount() {
            document.addEventListener('mousedown', this.handleClickOutside);
        }
    
        componentWillUnmount() {
            document.removeEventListener('mousedown', this.handleClickOutside);
        }
    
        /**
         * Alert if clicked on outside of element
         */
        handleClickOutside(event) {
            if (this.wrapperRef && !this.wrapperRef.current.contains(event.target)) {
                alert('You clicked outside of me!');
            }
        }
    
        render() {
            return 
    {this.props.children}
    ; } } OutsideAlerter.propTypes = { children: PropTypes.element.isRequired, };

    Hooks Implementation:

    import React, { useRef, useEffect } from "react";
    
    /**
     * Hook that alerts clicks outside of the passed ref
     */
    function useOutsideAlerter(ref) {
        useEffect(() => {
            /**
             * Alert if clicked on outside of element
             */
            function handleClickOutside(event) {
                if (ref.current && !ref.current.contains(event.target)) {
                    alert("You clicked outside of me!");
                }
            }
    
            // 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 OutsideAlerter(props) {
        const wrapperRef = useRef(null);
        useOutsideAlerter(wrapperRef);
    
        return 
    {props.children}
    ; }

提交回复
热议问题