使用 React Hook 的 OutSider 点击事件

OutSider click event using React Hook

我正在尝试为 DOM 元素开发一个点击事件处理函数,这样当我点击到 div 外部时,相应的 dom 元素就会关闭。我一直在尝试以下代码,但收到 TypeError: node.contains is not a function 的错误。不确定我是否正确地使用反应钩子。任何形式的帮助将不胜感激。

import React, { useState, useEffect, useRef } from 'react';

    const OutSiderClickComponent = () => {
    const [visible, setVisible] = useState(false);
    const node = useRef();

    const handleClick = () => {
      if (!visible) {
        document.addEventListener('click', handleOutsideClick, false);
       } else {
        document.removeEventListener('click', handleOutsideClick, false);
     }
     setVisible(prevState => ({
     visible: !prevState.visible,
     }));
   }

   const handleOutsideClick = (e) => {
      if (node.contains(e.target)) {
          return;
    }
    handleClick();
    }
    return(
        <div ref={node}>
            <button onClick={handleClick}>Click to See</button>
                {visible && <div>You Clicked the Button</div>}
        </div>
       );
     };


 export default OutSiderClickComponent; 

当您使用 useRef 时,您需要记住该值位于 refcurrent 属性中。

尝试node.current.contains()

其余的应该看起来更像,使用 React.useEffect:

const handleOutsideClick = (e) => {
    if (node.current.contains(e.target)) {
        console.log('clicked inside');
        // this.setVisible(true);
    } else {
        this.setVisible(false);
    }
}   

React.useEffect(() => {
    document.addEventListener('click', handleOutsideClick, false);
    return () => void document.removeEventListener('click', handleOutsideClick, false);
}, []);

<button onClick={() => void setVisible(true)}>Click to See</button>

有两个变化。首先,您需要使用 node.current 来检查 ref, node.current.contains(e.target)。此外,ref 必须附加到您需要检测外部点击的节点

var { useState, useEffect, useRef } =  React;

    const OutSiderClickComponent = () => {
    const [visible, setVisible] = useState(false);
    const node = useRef();

    const handleClick = () => {
      if (!visible) {
        document.addEventListener('click', handleOutsideClick, false);
       } else {
        document.removeEventListener('click', handleOutsideClick, false);
     }
     setVisible(prevState => ({
     visible: !prevState.visible,
     }));
   }

   const handleOutsideClick = (e) => {
      if (node.current.contains(e.target)) {
          return;
      }
      setVisible(prev => !prev.visible)
    }
    return(
        <div>
            <button onClick={handleClick}>Click to See</button>
                {visible && <div ref={node}>You Clicked the Button</div>}
        </div>
       );
     };
     
     
ReactDOM.render(<OutSiderClickComponent />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app" />