Reactコンポーネント外でのクリックを検出する 質問する

Reactコンポーネント外でのクリックを検出する 質問する

コンポーネント外でクリックイベントが発生したかどうかを検出する方法を探しています。記事jQuery のclosest() は、クリック イベントのターゲットにその親の 1 つとして dom 要素があるかどうかを確認するために使用されます。一致する場合、クリック イベントは子の 1 つに属しているため、コンポーネントの外部にあるとは見なされません。

そこで、コンポーネントで、クリック ハンドラーを にアタッチしますwindow。ハンドラーが起動したら、ターゲットをコンポーネントの dom の子と比較する必要があります。

クリック イベントには、イベントが移動した DOM パスを保持していると思われる「path」などのプロパティが含まれています。何を比較するか、またはどのようにトラバースするのが最適かはわかりませんが、誰かがすでにそれを巧妙なユーティリティ関数に組み込んでいるに違いないと思っています... 違いますか?

ベストアンサー1

次のソリューションは ES6 を使用し、メソッドを通じて ref を設定するだけでなく、バ​​インディングに関するベスト プラクティスに従います。

実際に動作する様子を見るには:

フックの実装:

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 <div ref={wrapperRef}>{props.children}</div>;
}

クラスの実装:

16.3以降

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 on outside of 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>;
  }
}

16.3以前

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 ref
   */
  setWrapperRef(node) {
    this.wrapperRef = node;
  }

  /**
   * Alert if clicked on outside of 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>;
  }
}

おすすめ記事