Событие клика OutSider с использованием React Hook - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь разработать функцию обработчика события щелчка для элемента 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; 

Ответы [ 2 ]

2 голосов
/ 09 мая 2019

Когда вы используете useRef, вы должны помнить, что значение находится в current атрибуте 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);
}, []);

и

<button onClick={() => void setVisible(true)}>Click to See</button>
0 голосов
/ 09 мая 2019

Есть два изменения. Во-первых, вам нужно использовать 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" />
...