使用 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
时,您需要记住该值位于 ref
的 current
属性中。
尝试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" />
我正在尝试为 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
时,您需要记住该值位于 ref
的 current
属性中。
尝试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" />