乐闻世界logo
搜索文章和话题

How to detect click outside on react component

2个答案

1
2

In React, detecting click events outside a component can typically be achieved through the following steps:

  1. Adding a global event listener: After the component mounts (using componentDidMount or useEffect), add a click event listener to document to capture all click events.

  2. Setting up a reference (Ref): Use useRef to create a reference and attach it to the component where you want to detect external clicks. This allows access to the actual DOM node to determine if the click event occurred within it.

  3. Detecting click position: When a global click event is triggered, use the target property of the event and compare it with the DOM node of your component to determine if the click occurred outside the component.

  4. Cleaning up the event listener: When the component unmounts (using componentWillUnmount or the cleanup function of useEffect), remove the event listener to prevent memory leaks.

Here is an example implementation using Hooks:

jsx
import React, { useEffect, useRef } from 'react'; function OutsideClickExample() { const wrapperRef = useRef(null); // Step 2 useEffect(() => { // Step 1 function handleClickOutside(event) { if (wrapperRef.current && !wrapperRef.current.contains(event.target)) { // Step 3 console.log('You clicked outside the component'); } } // Add event listener to document document.addEventListener('mousedown', handleClickOutside); // Step 4 return () => { // Remove event listener on unmount document.removeEventListener('mousedown', handleClickOutside); }; }, [wrapperRef]); return ( <div ref={wrapperRef}> <p>Click outside this area to try!</p> </div> ); } export default OutsideClickExample;

In this example, useEffect ensures the event listener is added only after the component mounts and removed when it unmounts. The ref provides a way to reference the actual DOM element, allowing us to determine if the click event occurred outside this element. Note that this example uses the mousedown event, which triggers immediately when the mouse button is pressed, rather than the click event which triggers when the button is released. Depending on your use case, you may need to choose a different event type.

2024年6月29日 12:07 回复

This solution uses ES6 and adheres to best practices for event binding and setting references via methods. See the practical implementation:

Hook Implementation:

javascript
import React, { useRef, useEffect } from "react"; /** * Hook that alerts clicks outside of the passed ref */ function useOutsideAlerter(ref) { useEffect(() => { /** * Alert if clicked outside the 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 cleanup 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 <div ref={wrapperRef}>{props.children}</div>; }

Class Implementation:

After 16.3

javascript
import React, { Component } from "react"; /** * Component that alerts if you click outside of it */ export default class OutsideAlerter extends Component { constructor(props) { super(props); this.wrapperRef = React.createRef(); this.handleClickOutside = this.handleClickOutside.bind(this); } componentDidMount() { document.addEventListener("mousedown", this.handleClickOutside); } componentWillUnmount() { document.removeEventListener("mousedown", this.handleClickOutside); } /** * Alert if clicked outside the element */ handleClickOutside(event) { if (this.wrapperRef && !this.wrapperRef.current.contains(event.target)) { alert("You clicked outside of me!"); } } render() { return <div ref={this.wrapperRef}>{this.props.children}</div>; } }

Before 16.3

javascript
import React, { Component } from "react"; /** * Component that alerts if you click outside of it */ export default class OutsideAlerter extends Component { constructor(props) { super(props); this.setWrapperRef = this.setWrapperRef.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); } componentDidMount() { document.addEventListener("mousedown", this.handleClickOutside); } componentWillUnmount() { document.removeEventListener("mousedown", this.handleClickOutside); } /** * Set the wrapper reference */ setWrapperRef(node) { this.wrapperRef = node; } /** * Alert if clicked outside the element */ handleClickOutside(event) { if (this.wrapperRef && !this.wrapperRef.contains(event.target)) { alert("You clicked outside of me!"); } } render() { return <div ref={this.setWrapperRef}>{this.props.children}</div>; } }
2024年6月29日 12:07 回复

你的答案