Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect click outside react parent component

How to know that user has clicked outside our react app which is pointed to

<div id="root">

(I'm having extra space to click outside root div)

I've tried the below code

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
        });
    console.log("clicked outside")
    }
}

But then, even if I clicked inside some child popup component under parent, it is showing as "clicked outside"

If I click anywhere inside the app (including children component), it should not say, "clicked outside"

So is there any way to know that the user clicked outside the complete app itself?

like image 489
Jithin Joseph Avatar asked Mar 22 '26 10:03

Jithin Joseph


1 Answers

The easiest way is to set a listener to the application container (the outmost element in the tree), instead of finding the id="root" element.

So, with given index.html:

<div id="root"></div>
<div>Div which outside of app</div>

Possible implementation can be (check the logs):

function useOnClickOutside(ref, handler) {
  useEffect(() => {
    const listener = event => {
      if (!ref.current || ref.current.contains(event.target)) {
        return;
      }

      handler(event);
    };

    document.addEventListener("mousedown", listener);
    document.addEventListener("touchstart", listener);

    return () => {
      document.removeEventListener("mousedown", listener);
      document.removeEventListener("touchstart", listener);
    };
  }, [ref, handler]);
}

const App = () => {
  const divRef = useRef();
  const handler = useCallback(() => console.log(`Click Outside`), []);
  useOnClickOutside(divRef, handler);

  return (
    <div
      ref={divRef}
      style={{
        margin: `0.5rem`,
        padding: `1rem`,
        border: `2px solid black`,
        cursor: `pointer`
      }}
    >
      Application
    </div>
  );
};

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

Edit currying-dust-cpscu

like image 179
Dennis Vash Avatar answered Mar 24 '26 00:03

Dennis Vash



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!