I am trying to make my web app display a message for a set amount of time whenever a button is pushed, and for said timer to reset whenever the button is pushed again before the time has elapsed. I feel dumb for even asking this, but how do I make it so that the button that starts a timer also resets it when the button is clicked again? Below is my code so far:
import { useState, useEffect } from "react";
export default function App() {
const [revealed, isRevealed] = useState(false);
const [time, setTime] = useState(0);
useEffect(() => {
let timer;
if (revealed) {
clearTimeout(timer);
setTime(2500);
timer = setTimeout(() => isRevealed(false), time);
}
}, [revealed]);
return (
<div>
<button onClick={() => isRevealed(true)}>Start!</button>
{revealed ? (
<p>
This should stay showing up if you keep clicking on the "Start!"
button.
</p>
) : null}
</div>
);
}
Here is the CodeSandbox demo of my code:
https://codesandbox.io/s/frosty-worker-g9l986?file=/src/App.js
2
Answers
Short answer:
clearTimeout()
https://developer.mozilla.org/en-US/docs/Web/API/clearTimeoutLong answer:
Move
timer
to the global scope so this can be used for clearing the timeout and resuse it.Also, the triggering of the timeout should be in the
onClick
handler instead ofuseEffect
. So the button should’ve beenSee you code in action: https://codesandbox.io/s/dazzling-almeida-xpm449?file=/src/App.js
you set revealed "true" when button is clicked and when revealed is true, click on button doesn’t do anything. the solution I can suggest is that set state in a way that every click on button could change it. for example use the time button is clicked. and to clear timeout you should use useEffect return.
import { useState, useEffect } from "react";