Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

92
Views
Problem when creating a timer using React Hook

I'm trying to create a timer with React Hook to use it on a Context. I have no problem when running it using Context and Vanilla JS, but when I use Hooks it seems to be a few miliseconds behind.

My useTimerHook:

import { useState } from 'react';

const useTimerHook = () => {
    const [minutes, setMinutes] = useState(0);
    const [seconds, setSeconds] = useState(0);
    const [miliSeconds, setMiliSeconds] = useState(0);

    function write() {
        let mt, st, mlst;
        setMiliSeconds(miliSeconds + 1);

        if (miliSeconds > 99) {
            setSeconds(seconds + 1);
            setMiliSeconds(0);
        }
        if (seconds > 59) {
            setMinutes(minutes + 1);
            setSeconds(0);
        }

        mlst = ('0' + miliSeconds).slice(-2);
        st = ('0' + seconds).slice(-2);
        mt = ('0' + minutes).slice(-2);

        return `${mt}:${st}:${mlst}`;
    }

        function reset() {
        setMinutes(0);
        setMiliSeconds(0);
        setSeconds(0);
    }
    return {
        write,
        reset,
    };
}; 

My Context:

import useTimerHook from '@hooks/useTimerHook';

const FightContext = createContext();

function FightProvider(props) {
    const [time, setTime] = useState('Presiona Start'); 
    const [status, setStatus] = useState(false);

    const { write: write, reset: reset } = useTimerHook();

    const startFight = () => {
        setStatus(true);        
    };

    const endFight = () => {        
        setStatus(false);
        reset();
    };

    useEffect(() => {
        if (status) {
            const timer = setTimeout(() => setTime(write()), 10);

            return () => {
                clearTimeout(timer);
            };
        }
    });

    return (
        <FightContext.Provider
            value={{
                time,               
                startFight,
                endFight,
                status,             
            }}
        >
            {props.children}
        </FightContext.Provider>
    );
}

export { FightContext, FightProvider };

As I said, when I try to run this the timer is slower than it should be. I.e, when my phone timer is at 15 seconds, the Hook timer is at 13.

I'm pretty sure that I missing something obvious here, or maybe I don't fully understand how Hooks and Context works.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Instead of keeping the "timer value" in the state, why not simply rely on the device time and apply any offset rules. I suggest keeping the start and stop timestamps in the state and then simply calculate the difference. Think of it like marking points on measuring tape and then calculating the difference. That way, issues such as frame times won't affect your timer value.

To display the clock "running" you can use setInterval(), e.g. every second or even faster and then display the difference between the start timestamp and timestamp for now().

To have an ability to pause and resume the timer, I would keep and array of objects of the form:

// example:
// [
//  {value: 0, type: "start"},
//  {value: 1000, type: "stop"},
//  {value: 5000, type: "start"},
// ]
const [timeStamps, setTimestamps] = useState([]);

To add a new timestamp to state:

const nextStampType
  = timeStamps.length > 0
  ? timeStamps[timeStamps.length - 1].type === "start" ? "stop" : "start"
  : "start";
setTimeStamps([...timestamps, {value: Date.now(), type: nextStampType}

Then you can use a utility function that loops over the array to calculate the timer value. Depending on your use case, you may either share the timer value or the timeStamps array via React Context.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!