使用React Hook的OutSider点击事件

时间:2019-05-09 07:03:14

标签: reactjs react-hooks

我正在尝试为DOM元素开发一个click事件处理函数,以便当我在div外部单击时,相应的dom元素关闭。我一直在尝试下面的代码,但出现TypeError: node.contains is not a function错误。不确定我是否使用react hook正确执行了操作。任何帮助将不胜感激。

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; 

2 个答案:

答案 0 :(得分:2)

使用useRef时,需要记住该值位于current的{​​{1}}属性中。

尝试ref

使用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);
}, []);

答案 1 :(得分:0)

有两个更改。首先,您需要使用node.current来检查引用, node.current.contains(e.target)。另外,裁判必须附加到您需要检测外部点击的节点上

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" />