Languages
[Edit]
EN

React - detect click outside component hook (works with nested elements)

10 points
Created by:
trincot
360

In this short article, we would like to show how in React write a custom hook that handles clicks outside component.

Hook to detect click outside of the component in React.
Hook to detect click outside of the component in React.

Note: presented in this article solution is able to handle outside clicks even clicked component contains nested elements.

Quick solution:

const useOutideClickHandler = onOutsideClick => {
    const ref = React.useRef(null);
    React.useEffect(() => {
        const handleWindowClick = e => {
            if (onOutsideClick) {
                let node = e.target;
                while (node) {
                    if (ref.current === node) {
                        return;
                    }
                    node = node.parentNode;
                }
                onOutsideClick();
            }
        };
        window.addEventListener('click', handleWindowClick);
        return () => {
            window.removeEventListener('click', handleWindowClick);
        };
    }, [onOutsideClick]);
    return ref;
};

// Usage example:

const elementRef = useOutideClickHandler(() => console.log('Outside clicked!'));

<div>
  <div ref={elementRef}>Content here ...</div>;
  Outside area ...
</div>

 

Practical example

To avoid unnecessary function recreation useOutideClickHandler() body was moved to addOutideClickListener() function.

// ONLINE-RUNNER:browser;

// import React from 'react';
// import ReactDOM from 'react-dom';

const addOutideClickListener = (ref, onOutsideClick) => {
    const handleWindowClick = e => {
        if (onOutsideClick) {
            let node = e.target;
            while (node) {
                if (ref.current === node) {
                    return;
                }
                node = node.parentNode;
            }
            onOutsideClick();
        }
    };
    window.addEventListener('click', handleWindowClick);
    return (): void => {
        window.removeEventListener('click', handleWindowClick);
    };
};

const useOutideClickHandler = onOutsideClick => {
    const ref = React.useRef(null);
    React.useEffect(() => addOutideClickListener(ref, onOutsideClick), [onOutsideClick]);
    return ref;
};

// Usage example:

const App = () => {
    const buttonRef = useOutideClickHandler(() => console.log('Outside button cliked!'));
    const divRef = useOutideClickHandler(() => console.log('Outside div cliked!'));
    return (
        <div>
          <button ref={buttonRef}>Click me!</button>
          <br /><br />
          <div ref={divRef} style={{padding: '10px', background: '#02d456'}}>
            Click me!
            <div style={{padding: '10px', background: '#feeba4'}}>
              Click me too! - it works when elements are nested too!
            </div>
          </div>
        </div>
    );
};

const root = document.querySelector('#root');
ReactDOM.render(<App />, root);
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.

ReactJS

React - detect click outside component hook (works with nested elements)
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join