简体   繁体   English

检测点击反应父组件外部

[英]Detect click outside react parent component

How to know that user has clicked outside our react app which is pointed to如何知道用户点击了我们指向的反应应用程序之外

<div id="root">

(I'm having extra space to click outside root div) (我有额外的空间可以在根 div 之外单击)

I've tried the below code我试过下面的代码

import ReactDOM from 'react-dom';
// ... ✂

componentDidMount() {
    document.addEventListener('click', this.handleClickOutside, true);
}

componentWillUnmount() {
    document.removeEventListener('click', this.handleClickOutside, true);
}

handleClickOutside = event => {
    const domNode = ReactDOM.findDOMNode(this);

    if (!domNode || !domNode.contains(event.target)) {
        this.setState({
            visible: false
        });
    console.log("clicked outside")
    }
}

But then, even if I clicked inside some child popup component under parent, it is showing as "clicked outside"但是,即使我在父级下的某个子弹出组件内部单击,它也显示为“在外部单击”

If I click anywhere inside the app (including children component), it should not say, "clicked outside"如果我点击应用程序内的任何地方(包括子组件),它不应该说,“点击外部”

So is there any way to know that the user clicked outside the complete app itself?那么有什么方法可以知道用户在整个应用程序之外点击了吗?

The easiest way is to set a listener to the application container (the outmost element in the tree), instead of finding the id="root" element.最简单的方法是为应用程序容器(树中最外面的元素)设置一个侦听器,而不是查找id="root"元素。

So, with given index.html :因此,使用给定index.html

<div id="root"></div>
<div>Div which outside of app</div>

Possible implementation can be (check the logs):可能的实现可以是(检查日志):

function useOnClickOutside(ref, handler) {
  useEffect(() => {
    const listener = event => {
      if (!ref.current || ref.current.contains(event.target)) {
        return;
      }

      handler(event);
    };

    document.addEventListener("mousedown", listener);
    document.addEventListener("touchstart", listener);

    return () => {
      document.removeEventListener("mousedown", listener);
      document.removeEventListener("touchstart", listener);
    };
  }, [ref, handler]);
}

const App = () => {
  const divRef = useRef();
  const handler = useCallback(() => console.log(`Click Outside`), []);
  useOnClickOutside(divRef, handler);

  return (
    <div
      ref={divRef}
      style={{
        margin: `0.5rem`,
        padding: `1rem`,
        border: `2px solid black`,
        cursor: `pointer`
      }}
    >
      Application
    </div>
  );
};

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

编辑 currying-dust-cpscu

There is a special component, just wrap your component in it and that's it...very convinient有一个特殊的组件,只需将您的组件包裹在其中就可以了……非常方便

import onClickOutside from "react-onclickoutside";

class MyComponent extends Component {
  handleClickOutside = evt => {
    // ..handling code goes here...
  };
}

export default onClickOutside(MyComponent);

https://github.com/Pomax/react-onclickoutside https://github.com/Pomax/react-onclickoutside

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM