[英]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.