tallpotato
tallpotato

Reputation: 153

Not sure how to include start/stop timer functionality in this app

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

Answers (1)

Ketan Ramteke
Ketan Ramteke

Reputation: 10675

Final Output :

enter image description here

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;

codesandbox.io

Upvotes: 1

Related Questions