Reputation: 153
Codesandbox I have a timer that runs in the background and records total time spent on a page. Currently, the timer only shows up when I hover over the button. Now I want this timer to start only when I hover over the button. Is there any way to implement that functionality?
import React, { useState, useEffect } from "react";
function App() {
const [isShown, setIsShown] = useState(false);
const[startTimer, setstartTimer] = useState(false);
const [time, setTime] = useState({
seconds: 0,
minutes: 0,
hours: 0
});
useEffect(() => {
let isCancelled = false;
const advanceTime = () => {
setTimeout(() => {
let nSeconds = time.seconds;
let nMinutes = time.minutes;
let nHours = time.hours;
nSeconds++;
if (nSeconds > 59) {
nMinutes++;
nSeconds = 0;
}
if (nMinutes > 59) {
nHours++;
nMinutes = 0;
}
if (nHours > 24) {
nHours = 0;
}
!isCancelled &&
setTime({ seconds: nSeconds, minutes: nMinutes, hours: nHours });
}, 1000);
};
advanceTime();
return () => {
//final time:
console.log(time);
isCancelled = true;
};
}, [time]);
return (
<div className="App">
<button
onMouseEnter={() => setIsShown(true)}
onMouseLeave={() => setIsShown(false)}
>
Hover over me!
</button>
{isShown && (
<div>
<p>
{`
${time.hours < 10 ? "0" + time.hours : time.hours} :
${time.minutes < 10 ? "0" + time.minutes : time.minutes} :
${time.seconds < 10 ? "0" + time.seconds : time.seconds}
`}
</p>
</div>
)}
</div>
);
}
export default App;
Upvotes: 0
Views: 64
Reputation: 10675
Final Output :
Use useRef
:
Here is the full implementation:
import React, { useState, useEffect, useRef } from "react";
function App() {
const [isShown, setIsShown] = useState(false);
const [time, setTime] = useState({
seconds: 0,
minutes: 0,
hours: 0
});
const funRef = useRef(null);
useEffect(() => {
let isCancelled = false;
if (isShown) {
funRef.current = setInterval(() => {
let nSeconds = time.seconds;
let nMinutes = time.minutes;
let nHours = time.hours;
nSeconds++;
if (nSeconds > 59) {
nMinutes++;
nSeconds = 0;
}
if (nMinutes > 59) {
nHours++;
nMinutes = 0;
}
if (nHours > 24) {
nHours = 0;
}
!isCancelled &&
setTime({ seconds: nSeconds, minutes: nMinutes, hours: nHours });
}, 1000);
}
return () => {
//final time:
console.log(time);
isCancelled = true;
};
}, [isShown, time]);
return (
<div className="App">
<button
onMouseEnter={() => setIsShown(true)}
onMouseLeave={() => setIsShown(false)}
>
Hover over me!
</button>
<p>
{`
${time.hours < 10 ? "0" + time.hours : time.hours} :
${time.minutes < 10 ? "0" + time.minutes : time.minutes} :
${time.seconds < 10 ? "0" + time.seconds : time.seconds}
`}
</p>
{isShown && (
<div>
<p>
{`
${time.hours < 10 ? "0" + time.hours : time.hours} :
${time.minutes < 10 ? "0" + time.minutes : time.minutes} :
${time.seconds < 10 ? "0" + time.seconds : time.seconds}
`}
</p>
</div>
)}
</div>
);
}
export default App;
Upvotes: 1