Need help with disappearing popup after onClick() event
Answered
chan posted this in #help-forum
chanOP
I'm creating a custom popup in React that shows up after a button click, and I want to go away from the screen after X amount of seconds. The issue I'm running into is that if you click the button multiple times before the initial timeout ends, you get very strange behavior like the popup jumping in and out or just not showing up at all.
I realize that this is due to me misusing React state, but I am not sure how to get around this issue/structure my code different. Can somebody please help me? I have tried multiple possible solutions for many hours but can't wrap my brain around it.
I realize that this is due to me misusing React state, but I am not sure how to get around this issue/structure my code different. Can somebody please help me? I have tried multiple possible solutions for many hours but can't wrap my brain around it.
function popupHandler(popupText, setPopupVis, setPopupText) {
setPopupText(popupText)
setPopupVis("visible");
// Works when you click a button ONCE and then don't touch anything during the timeout windows
// Totally breaks if you do otherwise.
// I want to "extend" the timeout so that the
// popup window keeps staying up if the button keeps getting clicked
setTimeout(() => {
setPopupVis("hidden")
}, 3000);
}
function CustomButton({setPopupText, setPopupVis}) {
return (
<button onClick={() => popupHandler("Dynamic string", setPopupText, setPopupVis)}>
I am a button
</button>
)
}
function MyPopUp({popupVis, popupText}) {
return (
<div style={{visibility: popupVis}}>
{popupText}
</div>
)
}
export default function MyContent() {
const [popupVis, setPopupVis] = useState('hidden');
const [popupText, setPopupText] = useState('')
return (
<>
<CustomButton setPopupText={setPopupText} setPopupVis={setPopupVis} />
<MyPopUp popupVis={popupVis} popupText={popupText} />
</>
)
}Answered by Ray
then add this to CustomerButton
function CustomerButton({setPopupText, setPopupVis}) {
const timerRef = useRef();
const handleClick = (popupText) => {
setPopupText(popupText)
setPopupVis("visible");
if (timerRef.current) clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => {
setPopupVis("hidden");
}, 300);
};
return (
<button onClick={() => handleClick("Dynamic string")}>I am a button</button>
)
}14 Replies
@chan I'm creating a custom popup in React that shows up after a button click, and I want to go away from the screen after X amount of seconds. The issue I'm running into is that if you click the button multiple times before the initial timeout ends, you get very strange behavior like the popup jumping in and out or just not showing up at all.
I realize that this is due to me misusing React state, but I am not sure how to get around this issue/structure my code different. Can somebody please help me? I have tried multiple possible solutions for many hours but can't wrap my brain around it.
function popupHandler(popupText, setPopupVis, setPopupText) {
setPopupText(popupText)
setPopupVis("visible");
// Works when you click a button ONCE and then don't touch anything during the timeout windows
// Totally breaks if you do otherwise.
// I want to "extend" the timeout so that the
// popup window keeps staying up if the button keeps getting clicked
setTimeout(() => {
setPopupVis("hidden")
}, 3000);
}
function CustomButton({setPopupText, setPopupVis}) {
return (
<button onClick={() => popupHandler("Dynamic string", setPopupText, setPopupVis)}>
I am a button
</button>
)
}
function MyPopUp({popupVis, popupText}) {
return (
<div style={{visibility: popupVis}}>
{popupText}
</div>
)
}
export default function MyContent() {
const [popupVis, setPopupVis] = useState('hidden');
const [popupText, setPopupText] = useState('')
return (
<>
<CustomButton setPopupText={setPopupText} setPopupVis={setPopupVis} />
<MyPopUp popupVis={popupVis} popupText={popupText} />
</>
)
}
try this
useEffect(() => {
if (popupVis==='visible') {
const timeout = setTimeout(() => {
setPopupVis("hidden");
}, 3000);
return () => {
clearTimeout(timeout);
};
}
}, [popupVis]);chanOP
I tested around with it and it still has strange behavior. If you continue clicking the button while the first timeout is counting down, your current popup will close once the first timeout is complete.
you want to reset the timer on every click?
chanOP
yes
then add this to CustomerButton
function CustomerButton({setPopupText, setPopupVis}) {
const timerRef = useRef();
const handleClick = (popupText) => {
setPopupText(popupText)
setPopupVis("visible");
if (timerRef.current) clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => {
setPopupVis("hidden");
}, 300);
};
return (
<button onClick={() => handleClick("Dynamic string")}>I am a button</button>
)
}Answer
@Ray then add this to CustomerButton
js
function CustomerButton({setPopupText, setPopupVis}) {
const timerRef = useRef();
const handleClick = (popupText) => {
setPopupText(popupText)
setPopupVis("visible");
if (timerRef.current) clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => {
setPopupVis("hidden");
}, 300);
};
return (
<button onClick={() => handleClick("Dynamic string")}>I am a button</button>
)
}
chanOP
okay, yes this ALMOST worked perfectly
I put the timerRef in MyContent and it worked
thank you!!!
eyes are opened after this experience. need to learn more about the React hooks besides just getState 😳
chanOP
this solution also works with getState()
thank you again