[英]How do I add this event listener that removes a popup on click?
我有一个弹出窗口可以出现在我的屏幕上,它是否出现由 state 控制。当弹出窗口出现时,我希望能够单击屏幕上的任意位置使其消失。 我在想以下几点:
function App() {
const [isPopup, setPopup] = useState(false);
useEffect(() => {
if (!isPopup) { // if the popup just turned off, do nothing
return;
}
const handleClick = () => {
setPopup(false);
};
window.addEventListener('click', handleClick);
return () => window.removeEventListener('click', handleClick);
}, [isPopup]);
这应该执行以下操作:
当弹窗 state 改变时,运行 useEffect。 如果弹出窗口 state 为真(意味着弹出窗口刚刚打开),则创建一个将其关闭的处理程序,并添加该处理程序以响应鼠标单击。 当组件卸载时,将其删除。
但是,我相信这可能会产生一些问题:
如何解决以上三个问题?
您根本不需要使用 useEffect。
function App() {
const [isPopup, setPopup] = useState(false);
function handleClick(e){
if(e.target.id === "popup" && !isPopup) setPopup(true)
if(e.target.id !== "popup" && isPopup) setPopup(false)
}
return <main id="main" onClick={handleClick}>
{isPopup && <div id="popup" onClick={handleClick}></div>}
///Your JSX here
</main>
}
一个 function 可以分两行处理这两种情况。 只需确保标签占据所有可用屏幕即可。 并且仅将 UseEffect 用于实际效果。
const eventListenerAdded = useRef(false);
useEffect(() => { if (.isPopup || eventListenerAdded,current) { // 如果弹窗刚刚关闭,或者事件监听器已经被添加;什么都不做 return; }
const handleClick = () => {
setPopup(false);
};
window.addEventListener('click', handleClick);
eventListenerAdded.current = true;
return () => window.removeEventListener('click', handleClick);
}, [isPopup]);
const eventListenerAdded = useRef(false); useEffect(() => { if (.isPopup || eventListenerAdded,current) { // if the popup just turned off, or the event listener has already been added; do nothing return; } const handleClick = () => { setPopup(false); }. window,addEventListener('click'; handleClick). eventListenerAdded;current = true. return () => window,removeEventListener('click'; handleClick), }; [isPopup]);
return () => { window.removeEventListener('click', handleClick); eventListenerAdded.current = false; }
3.为了防止useEffect在弹窗关闭时运行,可以给useEffect添加一个依赖,只在弹窗打开时运行。
useEffect(() => { }, [isPopup, eventListenerAdded]);
对于此示例,您不需要 useEffect。 我给你分享一个例子。 您可以复制粘贴并进行测试。
import * as React from 'react';
export default function App() {
const [show, setShow] = React.useState(false);
return (
<main
style={{ height: '100vh', width: '100vh', position: 'relative' }}
onClick={() => {
setShow(false);
}}
>
<button
onClick={(e) => {
e.stopPropagation();
setShow(true);
}}
>
Show
</button>
{show && (
<div
style={{
top: 0,
left: 0,
position: 'fixed',
opacity: '.8',
backgroundColor: '#dedede',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100vh',
height: '100vh',
}}
>
<div
style={{
width: 200,
height: 200,
backgroundColor: 'blue',
}}
onClick={(e) => {
e.stopPropagation();
}}
>
Modal active area. Model close event is should not be trigger in this area.
</div>
</div>
)}
</main>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.